如何作为一个模块的孩子路由到一个模块 – Angular 2 RC 5

我正在升级正在处理最新的Angular 2候选版本的应用程序。 作为这项工作的一部分,我尝试使用NgModule规范,并将我的应用程序的所有部分迁移到模块中。 除了路由问题之外,大部分情况已经非常好了。

"@angular/common": "2.0.0-rc.5", "@angular/compiler": "2.0.0-rc.5", "@angular/core": "2.0.0-rc.5", "@angular/forms": "0.3.0", "@angular/http": "2.0.0-rc.5", "@angular/platform-browser": "2.0.0-rc.5", "@angular/platform-browser-dynamic": "2.0.0-rc.5", "@angular/router": "3.0.0-rc.1", 

我的应用程序是作为模块的组合构build的,有几个模块作为父模块的子模块粘在一起。 例如,我有一个由通知模块,用户模块和电话模块(例如)组成的pipe理模块。 这些模块的路线应该看起来像…

 /admin/notifications/my-notifications /admin/users/new-user /admin/telephony/whatever 

在路由器的早期版本中,使用“children”很容易实现,

 export const AdminRoutes: RouterConfig = [ { path: "Admin", component: AdminComponent, Children: [ ...UserRoutes, ...TelephonyRoutes, ...NotificationRoutes ] } ] 

在另一个文件中,作为子模块的一部分,我也定义了单独的模块路由

 export const UserRoutes: RouterConfig = [ { path: "users", component: userComponent, children: [ {path: "new-user", component: newUserComponent} ] } ] 

这一切工作得很好。 在升级到Modules的过程中,我把所有东西都移到了自己的路由文件中,所以现在看起来更像这样

 const AdminRoutes: Routes = [ {path: "admin", component: AdminComponent} ] export const adminRouting = RouterModule.forChild(AdminRoutes) 

 const UserRoutes: Routes = [ path: "users", component: userComponent, children: [ {path: "new-user", component: newUserComponent} ] ] export const userRouting = RouterModule.forChild(UserRoutes) 

随着所有这一切,我有一个用户模块导入userRouting,然后一个AdminModule导入adminRoutes和UsersModule。 我的想法是,因为UsersModule是AdminModule的孩子,路由将工作的方式。 不幸的是,它不会最终导致用户路由

 /users/new-user 

代替

 /admin/users/new-user 

此外,正因为如此,新的用户组件并没有加载到我的pipe理组件的路由器sockets,这抛出了我的应用程序的样式和导航。

我不能为我的生活提出如何引用我的UserModule的路由作为我的AdminModule的子节点。 我试过这样做的旧方法,并得到两个模块中的路线错误。 很显然,由于这是最新发布的,这些案例中的一些文档是有限的。

任何人可以提供帮助将不胜感激!

好吧,在这个周末的更好的一部分摆弄这个之后,我把它运行到了最后。 最终对我有用的是做到以下几点:

  • 导出每个你想要Routes的模块的所有Routes 。 不要在子模块中导入任何RouterModule.forChild()
  • 导出子模块定义中的子项path定义中可见的每个组件。
  • 像往常一样导入(意味着Typescript import关键字)所有子路由,并使用...运算符将这些path合并到正确的path下。 我不能让它与定义path的子模块一起工作,但在父项上工作正常(并且与延迟加载兼容)。

就我而言,我有三个级别,像这样:

  • 根( /
    • 编辑器( editor/:projectId
      • 查询( query/:queryId
      • 页面( page/:pageId
    • 前面( about

以下定义适用于/editor/:projectId/query/:queryIdpath:

 // app.routes.ts import {editorRoutes} from './editor/editor.routes' // Relevant excerpt how to load those routes, notice that the "editor/:projectId" // part is defined on the parent { path: '', children: [ { path: 'editor/:projectId', children: [...editorRoutes] //loadChildren: '/app/editor/editor.module' }, ] } 

编辑器的路线如下所示:

 // app/editor/editor.routes.ts import {queryEditorRoutes} from './query/query-editor.routes' import {pageEditorRoutes} from './page/page-editor.routes' { path: "", // Path is defined in parent component : EditorComponent, children : [ { path: 'query', children: [...queryEditorRoutes] //loadChildren: '/app/editor/query/query-editor.module' }, { path: 'page', children: [...pageEditorRoutes] //loadChildren: '/app/editor/page/page-editor.module' } ] } 

QueryEditor的最后一部分如下所示:

 // app/editor/query/query-editor.routes.ts { path: "", component : QueryEditorHostComponent, children : [ { path: 'create', component : QueryCreateComponent }, { path: ':queryId', component : QueryEditorComponent } ] } 

但是,为了使这个工作, Editor需要导入导出QueryEditorQueryEditor需要导出QueryCreateComponentQueryEditorComponent因为这些导入是可见的。 不这样做会得到你错误的Component XYZ is defined in multiple modules

请注意,延迟加载也适用于此设置,在这种情况下,子path当然不应该被导入。

我有同样的问题。

使用loadChildren这里的答案很不错:

  { path: 'mypath', loadChildren : () => myModule } 

https://github.com/angular/angular/issues/10958

我find了解决这个问题的方法。 基本上,我正在按照以前的方式来定义我的路线,但是这次是在儿童的最高层。 例如我的pipe理路线:

 const AdminRoutes: Routes = [ { path: 'admin', component: AdminComponent, children: [ ...setupRoutes ] } ] export const adminRouting = RouterModule.forChild(AdminRoutes) 

我的设置路由文件是从一个子区域导入的,它定义了它自己的路由,包括更多的子节点。 问题是这个文件导出了“Routes”对象而不是RouterModule.forChild结果。

在设置之后,我从子模块定义中删除了子和子子系统。 然后,我必须从每个子模块中导出路线中使用的所有组件,就像上面提到的Marcus一样。 一旦我这样做了,路线开始工作,就像我想要的那样。

我不认为我真的很喜欢这个解决scheme,因为我的父模块知道太多的子模块路由。 但至lessRC5是一种简单的方法,它不会泄漏我所有的组件。 自从他把我放在正确的轨道上以后,我会继续把马库斯的回答标记为答案。

我得到了这个工作,除非你真的需要渲染层次结构中的所有父组件,我认为我的解决scheme更加优雅。

理解我的方法的关键是所有的路由,无论嵌套在模块中的深度如何被添加到根模块。 快速示例,比方说,我们有一个DepartmentModule和一个EmployeeModule ,我们想要使用这个URL导航到

 /department/1/employee/2 

在这一点上,我们会看到员工2的细节。 configurationdepartment中的department.routing.tsemployee中的employee.routing.ts路由将无法按照我们的计划进行,您将注意到可以导航到

 /employee/2 

从根组件,而同时

 /department/1/employee/2 

会崩溃(找不到路线)。 这种情况下的典型路由configuration如下所示:

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

值得注意的是,只要您导航到employee URL, DepartmentModule就不会占用活动部分,但您仍然可以访问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']); } } 

我想知道这是否应该是官方的做法,但是现在这个对我来说是有效的,直到Angular 2团队的下一次突破。

我觉得2.0.0 rc5现在不感兴趣。 但是在Angular 4中工作,也可能是早期的。

 @NgModule({ imports: [ RouterModule.forRoot([ {path: "", redirectTo: "test-sample", pathMatch: "full"}, { path: "test-sample", loadChildren: () => TestSampleModule } ]) ], exports: [RouterModule], declarations: [] }) export class AppRoutingModule{} @NgModule({ imports: [ RouterModule.forChild([{ path: "", component: TestSampleComponent, children: [ {path: "", redirectTo: "home", pathMatch: "full"}, { path: "home", loadChildren: () => HomeModule }, { path: "about", loadChildren: () => AboutModule } ] } ]) ], exports: [RouterModule], declarations: [] }) export class TestSampleRoutingModule {} @NgModule({ imports: [RouterModule.forChild([{ path: "", component: AboutComponent } ])], exports: [RouterModule] }) export class AboutRoutingModule {} 

考虑loadChildren: () => {...} 。 这不是懒加载。

详情请见:feat:支持NgModules层次sans延迟加载

在使用ngModules和RC5时,父模块的路由configuration不需要知道有关子模块路由的任何信息。 你只需要在这里为你的父模块定义路由。 此外,您必须将子模块导入到父模块中。 在子模块中,你必须这样定义你的路线:

 export const childRoutes: Routes = [ { path: 'someChild', component: SomeChildComponent, children: [ { path: '', component: SomeChildSubComponent1 }, { path: 'comp1', component: SomeChildSubComponent1 }, { path: 'comp2', component: SomeChildSubComponent2 } ] } ]; 

这会让你有一个像/ someParent / someChild / comp1这样的url,并且组件会显示在相应的router-outlet中。 请注意:您必须删除空path的组件。 否则,你无法导航到你的孩子。

使用loadChildren 。 没关系。 但是当你重新开始构build过程时,你会得到构build错误。 您应该将导出的符号与loadChildren

 import { ChildModule } from './child/child.module'; export function childRouteFactory() { return ChildModule; } ... { path: 'child', loadChildren: childRouteFactory } ...