【问题标题】:Dynamically loaded module causes Angular `<router-outlet>` to display twice动态加载的模块导致 Angular `<router-outlet>` 显示两次
【发布时间】:2020-05-12 09:15:00
【问题描述】:

解决方案在 Angular &lt;router-outlet&gt; displays template twice 中的某处,但我无法应用它,因为我的示例因动态加载的模块而有所不同。

我有一个嵌套的&lt;router-outlet&gt; 设置;

  • localhost:4200/login 在顶级组件AppComponent 中呈现LoginComponent
  • localhost:4200/main 在顶级组件AppComponent 中呈现MainComponent
    • MainComponent 包含一个 &lt;router-outlet&gt;,其中呈现了 LeafComponent

应用结构:

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

以下内容取自app.moduleiff main-module动态加载的。 IE。它仅在 main-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 },
];

这行得通。但是当动态加载LeafModule 时,MainComponent 会被渲染两次。 IE。当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 | Nested Routing with Multiple RouterOutlet using loadChildren having own Router Modules Example Application 可能是具有延迟加载模块的嵌套路由的最简单和最完整的示例 (IMO)。它还使用最新版本的 Angular,因此使用了新的负载 loadChildren: () =&gt; import('./foo.module').then(m =&gt; m.FooModule) 语法。它还有一个StackBlitz demo

【问题讨论】:

    标签: angular typescript angular-routing angular-router angular-module


    【解决方案1】:

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

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

    【讨论】:

    • 正确,感谢您的回答; leaf-module 没有路由模块,但是,我为该模块定义了一个 entry component。我假设这在延迟加载时为模块提供了一个入口点。
    猜你喜欢
    • 2017-09-17
    • 2021-09-27
    • 2019-09-20
    • 1970-01-01
    • 2020-11-23
    • 2020-07-27
    • 2020-01-19
    • 1970-01-01
    • 2017-06-11
    相关资源
    最近更新 更多