2016-09-21 22 views
2

我不能因为cookie的爱而弄清楚如何配置Angular 2路由器的最新版本(最终版本的版本)。我有一个相当大的Angular 2 RC5应用程序正在运行,但现在需要迁移到最终版本,然后才能继续。嵌套模块的路由应该如何在Angular 2中工作?

在这个应用程序中,我有很多嵌套的组件,根据谷歌的文档,应该组织模块中的功能。在我的应用程序的典型URL看起来像这样

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

但也有一些人,比如

user/34/settings 

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

我已经阅读了文档,这些文档相当冗长,并不急于切入正题,只是发现这个案例根本没有涉及。我不能相信这种情况不会奏效,这似乎是一个巨大的疏忽,所以我认为问题是我没有完全理解这个路由器的实际工作方式 - 而且我有一种感觉,不是唯一的一个。

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

在这种plunker我筑巢

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

就足以使问题出现2级。预期的结果是,我可以导航到

benutzer/78/klient/56 

即路由器实际上发现这条路线,这在目前是没有。

之前,我感动代码plunker并添加dashboard.component(因为我不能轻易修改plunker的URL,所以我不得不求助于routerLink)我居然可以浏览到

klient/56 

该不该”不可能。看起来,在另一个模块中定义的每条路由都被添加到根目录,而不是相互建立。

任何帮助,这是非常感谢。

回答

9

看看你所有的路线。

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 } 
] 

我说这个选项是更具侵入性,因为它迫使孩子们了解父母。在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 } 
]; 

在这种情况下,我们会从他们的父母@NgModule删除所有的子模块导入。这允许延迟加载模块。如果我们离开了,那么模块会在启动时急切地加载,但不会产生预期的效果(因此我为什么说我不是如何热切地这样做)。

另请注意loadChildren。在上面的例子中,我使用app作为根。唯一的原因是我在当地环境中进行了测试。我不是Plunker的忠实粉丝。尽管如此,你应该使用src作为根。

IMO,延迟加载看起来清洁剂,因为孩子不知道父母,但是这力量你懒洋洋地加载模块,这可能是不期望的。但在某些情况下,这是所希望的,因为它允许较轻的初始负载。

更多关于延迟加载,请参阅该文档上Asynchronous Routing

+0

的确,有很多文档,这个真实世界的场景根本没有处理。实际上,他们暗示嵌套的模块/路线,但他们从来没有拿出一个例子,所以我猜测他们只是略过了这个功能的最后。 –

+0

标记为答案,因为使用延迟加载的替代解决方案,这是我最终解决的问题。 –

+1

我也挑选了第二个解决方案,但它让我感到厌烦,这样一个简单的事情还没有实现。 – Mikki

1

发现了一个可能的解决方案,从https://stackoverflow.com/a/39629949/370935

复制我的回答我这还有工作,除非你确实需要渲染层次结构中的所有父组件,我认为我的解决方案是更为优雅。

理解我的方法的关键是所有的路由,无论嵌套在模块中的深度如何被添加到根模块。简单的例子,假设我们有一个DepartmentModuleEmployeeModule我们希望导航到使用此URL

/department/1/employee/2 

在这一点,我们会看到员工2的详细信息。在employee.routing.ts配置在department.routing.tsdepartmentemployee路由将工作方式,我们预期,你会发现,你可以浏览到

/employee/2 

从根组件,而

/department/1/employee/2 

会崩溃(找不到路线)。在这种情况下典型的路由配置是这样的:

export const departmentRoutes: Routes = [ 
    { path: 'department', component: DepartmentComponent, children: [ 
     { path: '', component: DepartmentsComponent }, 
     { path: ':id', component: DepartmentDetailsComponent } 
    ]} 
]; 

export const employeeRoutes: Routes = [ 
    { path: 'employee', component: EmployeeComponent, children: [ 
     { path: '', component: EmployeesComponent }, 
     { path: ':id', component: EmployeeDetailsComponent } 
    ]} 
]; 

EmployeeModule将由DepartmentModule进口。现在,就像我说的那样,这不起作用。

但是,只有一个单一的变化时将会:

export const employeeRoutes: Routes = [ 
    { path: 'department/:id/employee', component: EmployeeComponent, children: [ 
     { path: '', component: EmployeesComponent }, 
     { path: ':id', component: EmployeeDetailsComponent } 
    ]} 
]; 

美中不足的是,DepartmentModule不积极参加了,因为很快你导航到employee URL,但您仍可以访问每一个参数从ActivatedRoute

export class EmployeeDetailsComponent { 
    departmentId: number; 
    employeeId: number; 
    constructor(route: ActivatedRoute) { 
     route.parent.params.subscribe(params => 
      this.departmentId= +params['id']) 
     route.params.subscribe(params => 
      this.employeeId= +params['id']); 
    } 
} 

我不知道这应该是官方的做法,但现在这个工作对我来说,直到从角2队的下一个重大更改。

+0

路由部分,我只是在考验和撰写[答案](http://stackoverflow.com/a/39630242/2587435)当你发布你的:-)我的答案的第一部分提供了与您的解决方案几乎相同的解决方案,但提供了延迟加载的第二个解决方案。一探究竟。 –

相关问题