angular - 动态加载的模块导致 Angular `` 显示两次
问题描述
对此的解决方案是Angular<router-outlet>
中的某处显示模板两次,但我无法应用它,因为我的示例由于动态加载的模块而有所不同。
我有一个嵌套<router-outlet>
设置;
localhost:4200/login
LoginComponent
在顶级组件中呈现,AppComponent
localhost:4200/main
MainComponent
在顶级组件中呈现,AppComponent
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
并在未 动态加载的情况下工作。即它只有在被实例化时才有效。main-module
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
会渲染两次。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 | 使用具有自己的路由器模块示例应用程序的 loadChildren 的具有多个 RouterOutlet 的嵌套路由,可能是具有延迟加载模块的嵌套路由的最简单和最完整的示例(IMO)。它还使用了最新版本的 Angular,因此也使用了新的加载loadChildren: () => import('./foo.module').then(m => m.FooModule)
语法。它还有一个StackBlitz 演示。
解决方案
我们缺少一些关键信息。Leaf.module 有它自己的路由器模块吗?例如一个叶子路由.module.ts。该路由模块应该反过来对加载 LeafComponent 的 '' 进行路径匹配。
如果您没有该路由模块,则该模块不知道要查找哪条路由,我假设问题与您链接到的人相同,但是您错过了 '' 路径叶路由模块。
推荐阅读
- javascript - 节点获取 JSON 问题
- list - 如何在 OCaml 中打印特定索引列表列表?
- android - onStartJob 没有在 API 30 上被调用
- c# - c# DocumentLoadedEvent 没有触发
- r - R中逻辑回归中的子集
- macos - 我在 Mac 中的 VScode 上不断收到此错误。我什至尝试重新安装它和扩展,但它不起作用
- javascript - 如何使用 async-await 使部分代码等到另一部分完成
- sharepoint - Outlook 加载项任务窗格和本地 SharePoint 2019
- cloudsim - 为什么在 cloudsim 中使用 PlaneLab cloudlets 工作负载的模拟结束时,一些虚拟机消失了?
- dart - return 和 => 之间的区别(粗箭头)