首页 > 解决方案 > 动态加载的模块导致 Angular `` 显示两次

问题描述

对此的解决方案是Angular<router-outlet>中的某处显示模板两次,但我无法应用它,因为我的示例由于动态加载的模块而有所不同。

我有一个嵌套<router-outlet>设置;

应用程序结构:

app.component.ts       <router-outlet>
components/
    login/
        login-component.ts
    main/
        main-module.ts
        main-component.ts       <router-outlet>
        components/
            leaf-component.ts

以下内容取自app.module并在 动态加载的情况下工作。即它只有在被实例化时才有效。main-modulemain-component

const redirectUnauthorizedToLogin = () => redirectUnauthorizedTo(['/login']);
const redirectLoggedInToMain = () => redirectLoggedInTo(['/main']);

const appRoutes: Routes = [
  {
    path: 'login',
    pathMatch: 'full',
    component: LoginComponent,
    canActivate: [AngularFireAuthGuard],
    data: { authGuardPipe: redirectLoggedInToMain },
  },
  {
    path: '',
    component: MainComponent,
    canActivate: [AngularFireAuthGuard],
    data: { authGuardPipe: redirectUnauthorizedToLogin },
    children: [

      { path: '', redirectTo: '/main', pathMatch: 'full' },
      // ----> Render leaf-component in main-component <router-outlet>
      {
        path: 'main',
        pathMatch: 'full',
        component: LeafComponent,
      },

    ],
  },
  { path: '**', component: PageNotFoundComponent },
];

这行得通。但是当动态加载 时LeafModuleMainComponent会渲染两次。main-module即当被动态加载然后 main-component被实例化时它不起作用。

const appRoutes: Routes = [
  {
    path: 'login',
    pathMatch: 'full',
    component: LoginComponent,
    canActivate: [AngularFireAuthGuard],
    data: { authGuardPipe: redirectLoggedInToMain },
  },
  {
    path: '',
    component: MainComponent,
    canActivate: [AngularFireAuthGuard],
    data: { authGuardPipe: redirectUnauthorizedToLogin },
    children: [

      { path: '', redirectTo: '/main', pathMatch: 'full' },
      // ----> Dynamically load leaf-module
      // ----> Render leaf-component in main-component <router-outlet>
      {
        path: 'main',
        pathMatch: 'full',
        loadChildren: () => import('./components/main/components/leaf/leaf.module').then(m => m.LeafModule)
      },

    ],
  },
  { path: '**', component: PageNotFoundComponent },
];

解决方案详情

@inge-olaisen 的建议解决了我的问题,但为了完整起见,我想在这里添加一些细节。

我的错误是没有意识到动态加载的模块必须(?)具有路由,即使该路由仅加载默认模块:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LeafComponent } from './leaf.component';

const routes: Routes = [
    {
        path: '',
        component: LeafComponent,
        pathMatch: 'full',
    },
];
@NgModule({
    imports: [
        RouterModule.forChild(routes),
    ],
    exports: [RouterModule]
})
export class LeafRoutingModule { }

这似乎仍然有点多余,因为没有路线。但是因为我想延迟加载组件,所以我必须添加它们。

我还使用了单独的路由模块,这确实使事情变得更清晰。

最后,Angular 8 | 使用具有自己的路由器模块示例应用程序的 loadChildren 的具有多个 RouterOutlet 的嵌套路由,可能是具有延迟加载模块的嵌套路由的最简单和最完整的示例(IMO)。它还使用了最新版本的 Angular,因此也使用了新的加载loadChildren: () => import('./foo.module').then(m => m.FooModule)语法。它还有一个StackBlitz 演示

标签: angulartypescriptangular-routingangular-routerangular-module

解决方案


我们缺少一些关键信息。Leaf.module 有它自己的路由器模块吗?例如一个叶子路由.module.ts。该路由模块应该反过来对加载 LeafComponent 的 '' 进行路径匹配。

如果您没有该路由模块,则该模块不知道要查找哪条路由,我假设问题与您链接到的人相同,但是您错过了 '' 路径叶路由模块。


推荐阅读