Angular 带有命名插座的延迟加载不工作

Angular lazy load with named outlet not working

我创建了一个产品文件夹,其中包含 products-home.component(parent)products-list.component(child) 带有命名插座。

使用延迟加载导航到 products-list 时,我得到 Error: Cannot match any routes. URL Segment: 'products'

这在急切加载时有效

app.module.ts

@NgModule({
  imports:      [ ...,ProductsModule ]
})

products.module.ts

@NgModule({
  imports: [
    RouterModule.forRoot([
      {
        path: "products",
        component: ProductsHomeComponent,
        children: [
          {
            path: "products-list",
            component: ProductsComponent,
            outlet: "content"
          }
        ]
      }
    ])
  ]
})

这在延迟加载时不起作用

app.module.ts

const LazyRoutes: Routes = [
  {
    path: 'products',
    loadChildren: './products/products.module#ProductsModule'
  }
];
@NgModule({
  imports:      [ RouterModule.forRoot(LazyRoutes) ]
})

products.module.ts

@NgModule({
  imports: [
    RouterModule.forChild([
      {
        path: "",
        component: ProductsHomeComponent,
        children: [
          {
            path: "products-list",
            component: ProductsComponent,
            outlet: "content"
          }
        ]
      }
    ])
  ]
})

Stackblitz

这是 angular 中的一个已知问题 - 22346 and 10981

When module is lazy load then parent component's path needs to be set as empty. This is the issue here, the child component with named outlet only works when parent has a path(non-empty).

我通过添加假路径使这个工作正常。

{
    path: "home", <--Here
    component: ProductsHomeComponent,
    children: [
      {
        path: "products-list",
        component: ProductsComponent,
        outlet: "content"
      }
    ]
}

由于路由配置已更改,我们必须将 routerLink 更改为 'products/home'

<a [routerLink]="['/products/home', { outlets: { 'content': ['products-list'] } }]">Navigate to Products(Products List)</a>

2021 更新...从 V7 测试到 V12

为了使用延迟加载模块的命名出口,您必须导航到定义路由器的组件内的模块页面。例如:

考虑一下:

lazyModule.component.ts

<div>
  <a [routerLink]="[{outlets: {namedRouter: 'innerComponent'}}]">Open Link in Named Route</a><br>
  <router-outlet></router-outlet>
  <router-outlet name = 'namedRouter'></router-outlet>
</div>

单击锚标记 在 'namedRouter' 出口显示名为 'innerComponent' 的路线。

HOWEVER...出于某种原因,从任何其他嵌套组件更改 'namedRouter' 的路由(无论它是否在同一模块中)不会工作。在代码方面:

nestedComp.component.ts

<div>
  <button [routerLink]="{outlets: {namedRouter: 'aValidRoute'}}">IT SHOULD WORK, BUT IT DOESN'T</button> <!--- This will fail to resolve the route if called within the conteXt of the lazy loaded module. --->
</div>

如果您想从其他组件动态更改路由,我建议您实现一个 Observable 元素(例如,在 lazyModule.component.ts 中),该元素侦听抛给它的路由并调用路由器更改.请参见下面的示例:

someService.ts

private routeBS: BehaviorSubject = new BehaviorSubject(null);
routeObs = this.routeBS.asObservable();

changeNamedRouterRoute(route: string): void {
  this.routeBS.next(route);
}

lazyModule.component.ts

<div>
   <router-outlet></router-outlet>
   <router-outlet name = 'namedRouter'></router-outlet>
 </div>

 export class LazyModuleComponent implements OnInit {
   
   constructor(
     private service: SomeServiceService,
     private router: Router,
     private route: ActivatedRoute
   ) {}

   ngOnInit() {
     this.service.routeObs.subscribe(res => {
       this.router.navigate([{outlets: {namedRouter: res}}], {relativeTo: this.route.parent}).then(acc => {
           // do something when the router gives you the nod
       }).catch(err => {
           console.log(err);
           // do something when the router event fails
       });
     });
   }
 }

在应直接将路由设置为 'namedRouter' 的其他组件中,通过构造函数注入 'someService' 服务,然后调用该服务的 changeNamedRouterRoute() 函数,将所需路由指定为唯一参数。

希望这对某人有所帮助,我被困在这个问题上将近 6 个小时,但互联网并没有给我任何坚实的休息时间。 GitHub issues 由于不活动而未关闭而关闭,但我相信有些人可能会发现这非常有用。

对我有用,

在lazy模块的“路由”中进行如下配置:

const routes: Routes = [
    {
      path: '',
      component: LazyDownloadComponent,
      children: [
        {
          path: 'test',
          outlet: 'left',
          loadChildren: () =>
            import('./modules/another.module').then(
              (m) => m.Another
            ),
        },
      ],
    },

父组件:

<router-outlet name="left"></router-outlet>

url 在浏览器中:

http://localhost:4200/parentComponent/(left:test)

注意路径和“(”之间的“/”

我希望这对某人有所帮助,就像@taffy 对我所做的那样