如何作为一个模块的孩子路由到一个模块 – 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/:queryId
path:
// 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
需要导入和导出QueryEditor
, QueryEditor
需要导出QueryCreateComponent
和QueryEditorComponent
因为这些导入是可见的。 不这样做会得到你错误的Component XYZ is defined in multiple modules
。
请注意,延迟加载也适用于此设置,在这种情况下,子path当然不应该被导入。
我有同样的问题。
使用loadChildren这里的答案很不错:
{ path: 'mypath', loadChildren : () => myModule }
我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.ts
和employee
中的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 } ...