带有嵌套路由器出口的 Angular 9 嵌套延迟加载模块 [英] angular 9 nested lazy loaded modules with nested router outlets

查看:28
本文介绍了带有嵌套路由器出口的 Angular 9 嵌套延迟加载模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

app.component 模板:

1 个应用模块:

import { NgModule } from "@angular/core";从@angular/platform-b​​rowser"导入 { BrowserModule };import { CoreModule } from "@core/core.module";从@routes/app-routing.module"导入 { AppRoutingModule };import { AppComponent } from "./app.component";从@angular/platform-b​​rowser/animations"导入 { BrowserAnimationsModule };@NgModule({声明:[AppComponent],进口:[BrowserModule,CoreModule,AppRoutingModule,BrowserAnimationsModule],提供者:[],引导程序:[AppComponent],})导出类 AppModule {}

2 app.component:

从@angular/core"导入{组件};@成分({选择器:rot-root",模板:` <router-outlet></router-outlet>`,//<====== ROOT ROUTER-OUTLETstyleUrls: [./app.component.scss"],})导出类 AppComponent {}

3 app-routing.module:

import { NgModule } from "@angular/core";从@angular/router"导入 { Routes, RouterModule };导出常量路由:路由 = [{路径:",路径匹配:前缀",loadChildren: () =>import("./main/main-routing.module").then((m) => m.MainRoutingModule),},];@NgModule({声明:[],进口:[RouterModule.forRoot(ROUTES, { enableTracing: false })],出口:[路由器模块],})导出类 AppRoutingModule {}

4 main-routing.module:

import { NgModule } from "@angular/core";从@angular/router"导入 { Routes, RouterModule };import { layoutModules } from "./layouts";import { MainLayoutViewComponent } from "./layouts/main-layout/views";导出常量子路由:路由 = [{路径:",路径匹配:前缀",component: MainLayoutViewComponent,//<==== DISPLAYED IN ROOT ROUTER-OUTLET儿童:[//<==== 儿童显示在子路由器出口 (6){路径:仪表板",loadChildren: () =>import("./dashboard/dashboard.module").then(m => m.DashboardModule)},//<==== 来自主文件夹的很多路线 - 与仪表板相同 ====>],},];@NgModule({声明:[],进口:[RouterModule.forChild(SUBROUTES),...布局模块],出口:[路由器模块],})导出类 MainRoutingModule {}

5 main-layout.module:

import { NgModule } from "@angular/core";从@shared/shared.module"导入 { SharedModule };//材质模块//<==== 大量材料进口 :D ====>//模块组件从./views"导入{视图};//<====== 这里我导入主布局视图从./containers"导入{容器};从./components"导入{组件};@NgModule({声明:[...视图,...容器,...组件],进口:[共享模块,//<==== 大量材料进口 :D ====>],})导出类 MainLayoutModule {}

6 main-layout-view.component:

import { Component, OnInit } from "@angular/core";import { Observable } from "rxjs";从@core/services"导入{ SidenavService};@成分({选择器:rot-main-layout-view",模板:`<rot-main-navbar></rot-main-navbar><mat-drawer-container autosize hasBackdrop><mat-drawer mode="over"[已打开]=已打开$ |异步"><rot-main-sidenav></rot-main-sidenav></垫子抽屉><div class="content-wrapper"><路由器插座></路由器插座><==== 子路由器插座

</mat-drawer-container>`,styleUrls: [./main-layout-view.component.scss"],})导出类 MainLayoutViewComponent 实现 OnInit {构造函数(私有_sidenavService: SidenavService){}ngOnInit(): 无效 {}get open$(): Observable{返回 this._sidenavService.opened$;}}

I'm trying to develop SPA using angular 9, I almost try to lazy load every component and all of its children. My problem arose when I tried to have router-outlet inside one of the lazy-loaded components and I want this router-outlet to be used to load children components (which is lazy-loaded also). when I do so, I always get all the nested lazy-loaded components loaded in the main router-outlet in the app.component.html instead of the router-outlet in the nested lazy-loaded component

app.component template:

<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 template:

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

dashboard template:

<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 { }

In a nutshell, the statistics component (a lazy-loaded component) is loaded in the router-outlet declared in the app.component template rather than in the router-outlet in the dashboard template and the dashboard component is unloaded

I tried to find the solution in angular.io but all that I got is about managing multiple outlets in the same component. Also, this is what is I got when googling this problem.

is there any solution for this?

解决方案

I had a similar issue! The problem on my side was that I imported the lazy-loaded Module and so the routing definition was visible for the app router-outlet.

If you need an example, feel free and write a comment.

UPDATE: 2021-08-24 added full code example

the following example can be extended indefinitely:

Folder structure:

1 app.module:

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 app.component:

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$;
  }
}

这篇关于带有嵌套路由器出口的 Angular 9 嵌套延迟加载模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆