【发布时间】:2020-05-12 09:15:00
【问题描述】:
解决方案在 Angular <router-outlet> displays template twice 中的某处,但我无法应用它,因为我的示例因动态加载的模块而有所不同。
我有一个嵌套的<router-outlet> 设置;
-
localhost:4200/login在顶级组件AppComponent中呈现LoginComponent -
localhost:4200/main在顶级组件AppComponent中呈现MainComponent-
MainComponent包含一个<router-outlet>,其中呈现了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.module,iff 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: () => import('./foo.module').then(m => m.FooModule) 语法。它还有一个StackBlitz demo。
【问题讨论】:
标签: angular typescript angular-routing angular-router angular-module