如何使用嵌套模块进行路由应该在Angular 2中工作?

Tho*_*der 2 angular2-routing angular2-router3 angular

我不能因为对饼干的喜爱而弄清楚如何配置Angular 2路由器的最新版本(最终版本中的那个).我有一个相当大的Angular 2 RC5应用程序启动并运行,但在我继续前进之前需要迁移到最终版本.

在这个应用程序中,我有很多嵌套组件,根据谷歌的文档,应该组织为模块中的功能.我的应用中的典型网址如此

user/34/section/95/client/13/<feature>
Run Code Online (Sandbox Code Playgroud)

但也有一些其他的,比如

user/34/settings
Run Code Online (Sandbox Code Playgroud)

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

我已经阅读了这些文档,这些文档相当冗长,并不急于切入追逐,只是发现这个案例根本没有涉及.我无法相信这种情况不会起作用,这似乎是一个巨大的疏忽,所以我想问题是我还没有完全理解这个路由器实际上是如何工作的 - 我感觉我是我不是唯一的一个.

我已经创建了这个plunker来说明我的观点.

在这个plunker我有2级嵌套

app -> benutzer (user) -> klient (client)
Run Code Online (Sandbox Code Playgroud)

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

benutzer/78/klient/56
Run Code Online (Sandbox Code Playgroud)

即路由器实际上找到了该路由,此时它没有.

在我将代码移动到plunker并添加之前dashboard.component(因为我无法在plunker中轻松修改URL,所以我不得不诉诸routerLink)我实际上可以导航到

klient/56
Run Code Online (Sandbox Code Playgroud)

这是不可能的.看起来在另一个模块中定义的每个路由都被添加到根目录而不是彼此重叠.

非常感谢任何帮助.

Pau*_*tha 9

看看你所有的路线.

appRoutes = [      // AppModule
  { path: '', redirectTo: 'dashaboard' },
  { path: 'dashboard', component: DashboardComponent
];
benutzerRoutes = [ // BenutzerModule
  { path: 'benutzer/:id', component BenutzerComponent }
];
klientRoutes = [   // KlinetModule
  { path: 'klient/:id', component: KlientComponent }
]
Run Code Online (Sandbox Code Playgroud)

导入模块的方式对路径的构造方式没有任何影响.如何构建它们只是基于我们如何构建它.你对此有何期待?

AppModule
   imports -> BenutzerModule
                   imports -> KlinetModule
Run Code Online (Sandbox Code Playgroud)

通往以下路线

dashboard/benutzer/:id/klient/:id
Run Code Online (Sandbox Code Playgroud)

事实并非如此.这些路由数组中的每一个都只是添加到根目录中.这就是为什么你可以访问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 }
]
Run Code Online (Sandbox Code Playgroud)

我说这个选项更具侵入性,因为它迫使孩子们了解父母.在Angular 2架构中,这与我们构建组件的方式相反.父母应该了解孩子,但不一定相反.

我能想到的另一个选择是使用loadChildren懒惰地加载子模块.我说"懒惰",因为我无法弄清楚如何做到这一点,并且不确定是否有可能这样做.为了让孩子们懒洋洋地加载,我们可以做到

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 }
];
Run Code Online (Sandbox Code Playgroud)

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

还要注意loadChildren.在上面的例子中,我app用作根.唯一的原因是我在当地环境中测试过.我不是普兰克的忠实粉丝.但是对于你的Plunker,你应该src用作root.

IMO,懒惰的加载看起来更干净,因为孩子不知道父母,但这迫使你懒惰加载模块,这可能是不希望的.但是在某些情况下,需要,因为它允许更轻的初始负载.

有关延迟加载的更多信息,请参阅异步路由上的docs routing部分