只有子路由激活时父组件才会被激活

问题描述 投票:0回答:1

我想要这样的路线结构:

如果我走“/sale”路线:

dashboard
  feature
    sale

如果我走“/”路线:

dashboard

也就是说,如果子路由没有激活,父路由也不应该激活。

我试过这个:

{
    path: "",
    component: DashboardComponent,
    providers: [ DashboardService, PopupService, NotificationsService ],
    resolve: { resolved: dashboardResolver },
    children: [
      {
        path: "",
        component: FeatureComponent,
        children: [
          {
            path: "sale",
            loadChildren: () => import("./features/sale/sale.module").then(module => module.SaleModule)
          },
          {
            path: "currents",
            loadChildren: () => import("./features/currents/currents.module").then(module => module.CurrentsModule)
          }
        ]
      }
    ],
  },

但这会激活功能组件,即使它位于“/”路径中。并且它不会为每个子路由重新创建功能组件。 我在这里寻找集中式解决方案,因为孩子的数量可能很多。

angular angular-routing angular-router
1个回答
0
投票

仅当子项(

canMatchFn
sale
)存在时,您可以使用
current
通过检查线段的长度来有条件地匹配特征路径。

用作 Route 上的 canMatch 防护的函数的签名。

const canMatchFn: CanMatchFn = (route: Route, segments: UrlSegment[]) => {
  console.log(route, segments);
  return segments?.length > 0;
};

路由将使用此函数来确定特征路由匹配。

bootstrapApplication(App, {
  providers: [
    provideAnimations(),
    provideRouter([
      {
        path: '',
        component: A,
        children: [
          {
            path: '',
            canMatch: [canMatchFn],
            component: B,

完整代码:

import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { provideAnimations } from '@angular/platform-browser/animations';
import {
  Route,
  RouterModule,
  provideRouter,
  CanMatchFn,
  UrlSegment,
} from '@angular/router';
import {
  trigger,
  animate,
  transition,
  style,
  query,
} from '@angular/animations';

export const fadeAnimation = trigger('fadeAnimation', [
  transition('* => *', [
    query(':enter', [style({ opacity: 0, position: 'absolute' })], {
      optional: true,
    }),
    query(
      ':leave',
      [
        style({ opacity: 1 }),
        animate('0.3s', style({ opacity: 0, position: 'absolute' })),
      ],
      { optional: true }
    ),
    query(
      ':enter',
      [
        style({ opacity: 0 }),
        animate('0.3s', style({ opacity: 1, position: 'relative' })),
      ],
      { optional: true }
    ),
  ]),
]);

@Component({
  selector: 'app-a',
  standalone: true,
  imports: [RouterModule],
  template: `
        A<br/><br/>
        <router-outlet/>
      `,
})
export class A {
  name = 'Angular';
}

@Component({
  selector: 'app-b',
  standalone: true,
  imports: [RouterModule],
  template: `
          B<br/><br/>
          <router-outlet/>
      `,
})
export class B {
  name = 'Angular';
}

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterModule, A, B],
  animations: [fadeAnimation],
  template: `
        <div class="container">
          <header class="my-3">
            <ul class="nav nav-pills">
              <li class="nav-item">
                <a class="nav-link" [routerLink]="['/']" routerLinkActive="active"
                  [routerLinkActiveOptions]="{ exact: true }">/</a>
              </li>
              <li class="nav-item">
                <a class="nav-link" [routerLink]="['/sale']" routerLinkActive="active">/sale</a>
              </li>
            </ul>
          </header>

          <main role="main" [@fadeAnimation]="outlet.isActivated ? outlet.activatedRoute : ''">
            <router-outlet #outlet="outlet"></router-outlet>
          </main>
        </div>
      `,
})
export class App {
  name = 'Angular';
}

    const canMatchFn: CanMatchFn = (route: Route, segments: UrlSegment[]) => {
      console.log(route, segments);
      return segments?.length > 0;
    };

bootstrapApplication(App, {
  providers: [
    provideAnimations(),
    provideRouter([
      {
        path: '',
        component: A,
        children: [
          {
            path: '',
            canMatch: [canMatchFn],
            component: B,
            children: [
              {
                path: 'sale',
                component: B,
              },
              {
                path: 'currents',
                component: B,
              },
            ],
          },
        ],
      },
    ]),
  ],
});

Stackblitz 演示

© www.soinside.com 2019 - 2024. All rights reserved.