angular - 使用嵌套模块的路由应该如何在 Angular 2 中工作?

标签 angular angular2-routing angular2-router3

由于对 cookie 的热爱,我无法弄清楚如何配置 Angular 2 路由器的最新版本(最终版本中的那个)。我有一个相当大的 Angular 2 RC5 应用程序正在运行,但现在需要迁移到最终版本才能继续。

在这个应用程序中,我有很多嵌套组件,根据 Google 的文档,这些组件应该组织为模块中的功能。我的应用程序中的典型 URL 如下所示

user/34/section/95/client/13/<feature>

还有一些其他的,比如

user/34/settings

所以在这种情况下,settings 将是一个功能模块。

我已经阅读了文档,这些文档相当啰嗦,并不急于切入正题,却发现根本没有涵盖这种情况。我不敢相信这种情况不会奏效,这似乎是一个巨大的疏忽,所以我想问题是我还没有完全理解这个路由器的实际工作原理——我有一种感觉我不是唯一的。

我创建了 this plunker来说明我的观点。

在这个 plunker 中我有 2 层嵌套

app -> benutzer (user) -> klient (client)

刚好足以使问题出现。预期的结果是我可以导航到

benutzer/78/klient/56

即路由器实际上找到了那条路线,但目前还没有。

在我把代码移到plunker上并添加了dashboard.component之前(因为我不能轻易修改plunker中的URL,所以我不得不求助于routerLink)我实际上可以导航到

klient/56

这应该是不可能的。似乎在另一个模块中定义的每个路由都被添加到根而不是在彼此之上构建。

非常感谢对此的任何帮助。

最佳答案

查看所有路线。

appRoutes = [      // AppModule
  { path: '', redirectTo: 'dashaboard' },
  { path: 'dashboard', component: DashboardComponent
];
benutzerRoutes = [ // BenutzerModule
  { path: 'benutzer/:id', component BenutzerComponent }
];
klientRoutes = [   // KlinetModule
  { path: 'klient/:id', component: KlientComponent }
]

导入模块的方式对路由的构建方式没有任何影响。它们的构建方式完全基于我们构建的方式。您对此有何期待

AppModule
   imports -> BenutzerModule
                   imports -> KlinetModule

通向以下路线

dashboard/benutzer/:id/klient/:id

事实并非如此。这些路由数组中的每一个都被简单地添加到根。这就是为什么您可以访问 klient/:id 而不是 dashboard/benutzer/:id

我已经阅读了几次关于路由的完整文档,并且没有任何在不同模块中嵌套路由的示例。所有示例都有从根路由加载的模块,就像您的示例一样,或者嵌套路由是同一路由配置的一部分。因此,由于没有示例,我想我们只需要使用我们所知道的并自行决定什么是最好的方法。

我可以想到几种方法。第一个,也是最明显但比下一个选项更具侵入性的 IMO,就是将完整的路由添加到路径中

appRoutes = [      // AppModule
  { path: '', redirectTo: 'dashaboard' },
  { path: 'dashboard', component: DashboardComponent
];
benutzerRoutes = [ // BenutzerModule
  { path: 'dashboard/benutzer/:id', component BenutzerComponent }
];
klientRoutes = [   // KlinetModule
  { path: 'dashboard/benutzer/:id/klient/:id', component: KlientComponent }
]

我说这个选项更具侵入性,因为它迫使 child 了解 parent 。在 Angular 2 架构中,这与我们构建组件的方式背道而驰。 parent 应该了解 child ,但反之则不一定。

我能想到的另一个选择是使用 loadChildren 延迟加载子模块。我说“懒惰地”是因为我无法弄清楚如何急切地做到这一点,并且不确定是否有可能这样做。要延迟加载 child ,我们可以这样做

export const appRoutes: Routes = [
  { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
  { path: 'dashboard', component: DashboardComponent },
  {
    path: 'dashboard/benutzer',
    loadChildren: 'app/benutzer/benutzer.module#BenutzerModule'
  },
  { path: '**', component: NotFoundComponent }
];
export const benutzerRoutes: Routes = [
  { path: ':id', component: BenutzerComponent },
  {
    path: ':id/klient',
    loadChildren: 'app/klienten/klienten.module#KlientenModule'
  }
];
export const klientenRoutes: Routes = [
  { path: ':id', component: KlientComponent }
];

在这种情况下,我们将从它们的父级 @NgModule 中删除所有子模块导入。这允许延迟加载模块。如果我们离开,那么模块将在启动时急切加载,但没有达到预期的效果(因此我说我不是如何急切地这样做)。

另请注意 loadChildren。在上面的示例中,我使用 app 作为根。唯一的原因是我在本地环境中进行了测试。我不是 Plunker 的忠实粉丝。不过,对于您的 Plunker,您应该使用 src 作为根。

IMO,延迟加载看起来更干净,因为 child 不知道父项,但这迫使您延迟加载模块,这可能不是您想要的。但在某些情况下,这是需要的,因为它允许更轻的初始负载。

有关延迟加载的更多信息,请参阅 Asynchronous Routing 上的文档路由部分

关于angular - 使用嵌套模块的路由应该如何在 Angular 2 中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39626072/

相关文章:

angular - ngAfterViewInit() 和 ngAfterViewChecked() 有什么区别?

javascript - 在 angular2 rc4 问题中找不到 RouteConfig 函数(纯 JS)

Angular2如何独立于html基本url设置应用程序根路径

angular - 隐藏ag-grid状态栏

angular - 禁用 ion-content 滚动

Angular 2 @Output 参数

angular - route.queryParams.subscribe 在 Angular Typescript 组件中返回未定义

javascript - Angular 2 中组件模板之外的 routerLink,在基本 html 中

带有父路由参数的 Angular 延迟加载

angular - 错误: No component factory found for TermsConditions