Angular 9 嵌套延迟加载模块,带有嵌套路由器出口
Posted
技术标签:
【中文标题】Angular 9 嵌套延迟加载模块,带有嵌套路由器出口【英文标题】:angular 9 nested lazy loaded modules with nested router outlets 【发布时间】: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 中找到解决方案,但我得到的只是在同一个组件中管理多个插座。另外,这是我在谷歌上搜索这个问题时得到的。
有什么解决办法吗?
【问题讨论】:
【参考方案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)
]
];
【讨论】:
这似乎是错误的,你试过你的代码吗?为了使您的代码正常工作,作者必须将<router-outlet>
放在DashboardComponent
中,这是不需要的,因为他想通过延迟加载独立加载DashboardModule
和StatisticsModule
以上是关于Angular 9 嵌套延迟加载模块,带有嵌套路由器出口的主要内容,如果未能解决你的问题,请参考以下文章
AngularJS“多重路由”嵌套模块——AngularJS“路由”嵌套学习资料教程
带有延迟加载路由的 Angular CLI HMR 热重载整个事情