【问题标题】:angular 9 nested lazy loaded modules with nested router outletsAngular 9 嵌套延迟加载模块,带有嵌套路由器出口
【发布时间】:2020-10-01 17:11:56
【问题描述】:

我正在尝试使用 Angular 9 开发 SPA,我几乎尝试延迟加载每个组件及其所有子组件。当我尝试在一个延迟加载的组件中使用路由器插座并且我希望此路由器插座用于加载子组件(这也是延迟加载的)时,我的问题出现了。 当我这样做时,我总是将所有嵌套的延迟加载组件加载到 app.component.html 的主路由器插座中,而不是嵌套延迟加载组件中的路由器插座

app.component 模板:

<app-navbar></app-navbar>
<router-outlet></router-outlet>

app-routing.module:

const routes: Routes = [
  { path: '', component: HomeComponent },
  { path: 'login', component: LoginComponent },
  { path: 'articles', loadChildren: () => import('./articles-viewer/articles-viewer.module').then(m => m.ArticlesViewerModule) },
  { path: 'dashboard', loadChildren: () => import('./dashboard/dashboard.module').then(m => m.DashboardModule) },
  { path: '**', redirectTo: ''}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

app.module:

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    LoginComponent,
    NavbarComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    BrowserAnimationsModule,
    AppAngularMaterial
  ],
  providers: [
    AppHttpInterceptors
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

navbar.component 模板:

<a routerLink="">Home</a>
<a routerLink="/articles">Articles</a>
<a routerLink="/dashboard">Dashboard</a>

仪表板模板:

<a routerLink="statistics">Statistics</a>
<router-outlet></router-outlet>

dashboard.module:

@NgModule({
  declarations: [DashboardComponent],
  imports: [
    CommonModule,
    DashboardRoutingModule,
    AppAngularMaterial
  ]
})
export class DashboardModule { }

dashboard-routing.module:

const routes: Routes = [
  { path: '', component: DashboardComponent },
  { path: 'statistics', loadChildren: () => import('./statistics/statistics.module').then(m => m.StatisticsModule) }
  ];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class DashboardRoutingModule { }

简而言之,统计组件(一个延迟加载的组件)被加载到 app.component 模板中声明的 router-outlet 中,而不是仪表板模板中的 router-outlet 中,并且仪表板组件被卸载

我试图在 angular.io 中找到解决方案,但我得到的只是在同一个组件中管理多个插座。另外,这是我在谷歌上搜索这个问题时得到的。

有什么解决办法吗?

【问题讨论】:

    标签: nested lazy-loading angular9 router-outlet


    【解决方案1】:

    我遇到了类似的问题!我这边的问题是我导入了延迟加载的模块,因此路由定义对于应用程序路由器出口是可见的。

    如果您需要示例,请随时发表评论。

    更新:2021-08-24 添加了完整代码示例

    下面的例子可以无限扩展:

    文件夹结构:

    1 应用程序模块:

    import { NgModule } from "@angular/core";
    import { BrowserModule } from "@angular/platform-browser";
    
    import { CoreModule } from "@core/core.module";
    import { AppRoutingModule } from "@routes/app-routing.module";
    
    import { AppComponent } from "./app.component";
    
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
    
    @NgModule({
      declarations: [AppComponent],
      imports: [BrowserModule, CoreModule, AppRoutingModule, BrowserAnimationsModule],
      providers: [],
      bootstrap: [AppComponent],
    })
    export class AppModule {}
    

    2 应用程序组件:

    import { Component } from "@angular/core";
    
    @Component({
      selector: "rot-root",
      template: ` <router-outlet></router-outlet> `, // <===== ROOT ROUTER-OUTLET
      styleUrls: ["./app.component.scss"],
    })
    export class AppComponent {}
    

    3 app-routing.module:

    import { NgModule } from "@angular/core";
    import { Routes, RouterModule } from "@angular/router";
    
    export const ROUTES: Routes = [
      {
        path: "",
        pathMatch: "prefix",
        loadChildren: () =>
          import("./main/main-routing.module").then((m) => m.MainRoutingModule),
      },
    ];
    
    @NgModule({
      declarations: [],
      imports: [
        RouterModule.forRoot(ROUTES, { enableTracing: false })
      ],
      exports: [RouterModule],
    })
    export class AppRoutingModule {}
    

    4 main-routing.module:

    import { NgModule } from "@angular/core";
    import { Routes, RouterModule } from "@angular/router";
    
    import { layoutModules } from "./layouts";
    
    import { MainLayoutViewComponent } from "./layouts/main-layout/views";
    
    export const SUBROUTES: Routes = [
      {
        path: "",
        pathMatch: "prefix",
        component: MainLayoutViewComponent, // <==== DISPLAYED IN ROOT ROUTER-OUTLET
        children: [ // <==== CHILDREN ARE DISPLAYED IN SUB ROUTER-OUTLET (6)
          {
            path: "dashboard",
            loadChildren: () => import("./dashboard/dashboard.module").then(m => m.DashboardModule)
          },
          // <==== A LOT OF ROUTES FROM THE MAIN FOLDER - SAME AS DASHBOARD ====>
        ],
      },
    ];
    
    @NgModule({
      declarations: [],
      imports: [
        RouterModule.forChild(SUBROUTES),
        ...layoutModules
      ],
      exports: [RouterModule],
    })
    export class MainRoutingModule {}
    
    

    5 main-layout.module:

    import { NgModule } from "@angular/core";
    import { SharedModule } from "@shared/shared.module";
    
    // material modules
    // <==== a lot of material imports :D ====>
    
    // module components
    import { views } from "./views"; // <===== HERE I IMPORT THE MAIN-LAYOUT-VIEW
    import { containers } from "./containers";
    import { components } from "./components";
    
    @NgModule({
      declarations: [...views, ...containers, ...components],
      imports: [
        SharedModule,
        // <==== a lot of material imports :D ====>
      ],
    })
    export class MainLayoutModule {}
    

    6 main-layout-view.component:

    import { Component, OnInit } from "@angular/core";
    
    import { Observable } from "rxjs";
    
    import { SidenavService } from "@core/services";
    
    @Component({
      selector: "rot-main-layout-view",
      template: `
        <rot-main-navbar></rot-main-navbar>
        <mat-drawer-container autosize hasBackdrop>
          <mat-drawer mode="over" [opened]="opened$ | async">
            <rot-main-sidenav></rot-main-sidenav>
          </mat-drawer>
          <div class="content-wrapper">
            <router-outlet></router-outlet>          <==== SUB ROUTER-OUTLET
          </div>
        </mat-drawer-container>
      `,
      styleUrls: ["./main-layout-view.component.scss"],
    })
    export class MainLayoutViewComponent implements OnInit {
    
      constructor(private _sidenavService: SidenavService) {}
    
      ngOnInit(): void {}
    
      get opened$(): Observable<boolean> {
        return this._sidenavService.opened$;
      }
    }
    
    

    【讨论】:

    • @Nikita 我添加了一个真实的代码示例。如果有不清楚的地方,请告诉我; )
    • 谢谢你,顺便说一句,关于我的情况,我正在将 Angular 模块转换为延迟加载并忘记将其从 AppModule 导入中删除((我已使用 enableTracing: true 调试路由器模块,并且发现路由配置中有一些冗余路由,然后我知道应该在某处注册路由并检查我的延迟加载模块的引用,发现我忘记将其从 AppModule 导入中删除
    【解决方案2】:

    在dashboard-routing.module中

    而不是这个:

    const routes: Routes = [
        { path: '', component: DashboardComponent },
        { path: 'statistics', loadChildren: () => 
            import('./statistics/statistics.module').then(m => m.StatisticsModule)
        }
    ];
    

    这样做:

    const routes: Routes = [
        { path: '', component: DashboardComponent,
          children: [
              { path: 'statistics', loadChildren: () => 
               import('./statistics/statistics.module').then(m => m.StatisticsModule)
              }
          ]
        }
    ];
    

    【讨论】:

    • 这似乎是错误的,你试过你的代码吗?为了使您的代码正常工作,作者必须将&lt;router-outlet&gt; 放在DashboardComponent 中,这是不需要的,因为他想通过延迟加载独立加载DashboardModuleStatisticsModule
    猜你喜欢
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-29
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多