如何在可重用(通用)模块中进行子路由?

时间:2018-03-02 08:41:46

标签: angular

我有一个自定义人员模块,我想打包,然后在不同的应用程序中重用。

@Component({
  selector: 'mod-person-grid',
  template: `<h1><ng-content></ng-content></h1>`
})
class PersonGridComponent { @Input() type: string; }

const personRoutes: Routes = [
  { 
     path: '',   
     component: PersonGridComponent,
      children: [
      {
        path: 'view/:id', 
        component: PersonDetailsComponent,
       }
    ]
  }
];

@NgModule({
  imports:      [ CommonModule, RouterModule.forChild(personRoutes) ],
  declarations: [ PersonGridComponent, PersonDetailsComponent ],
  exports: [ PersonGridComponent ]
})
export class PersonModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: PersonModule,
      providers: [ PersonService ]
    }
  }
}

因此,我可以拥有一个员工应用程序,该应用程序使用人员组件查看员工,并在选择特定员工时查看其详细信息。

或者我将有一个学生申请表,我使用同一个人模块查看所有类型的学生&#39;点击特定学生后,显示其详细信息。

但是,根据父应用程序(员工或学生)链接,我无法在网格和详细视图之间的此人员模块中使用路由。

这是一个展示我想做的事情:routing_in_module

我的EmployeeComponent使用&#34;员工&#34;路线和StudentComponent使用&#34;学生&#34;路由。

@Component({
  template: `<mod-person-grid [type]="'staff'">Manage Employees</mod-person-grid>`
})
class EmployeesComponent { }

@Component({
  template: `<mod-person-grid [type]="'student'">Manage Students</mod-person-grid>`
})
class StudentsComponent { }

const appRoutes: Routes = [
  { path: '',   redirectTo: '/home', pathMatch: 'full' },
  { path: 'home',  component: HomeComponent },
  { path: 'employees',  component: EmployeesComponent },
  { path: 'students',  component: StudentsComponent },
];

@NgModule({
  imports: [ BrowserModule, RouterModule.forRoot(appRoutes), PersonModule.forRoot() ],
  declarations: [ App, HomeComponent, EmployeesComponent, StudentsComponent ],
  bootstrap: [ App ]
})
export class AppModule {}

目标是让PersonModule尽可能通用。

我如何路线给孩子&#34;查看&#34; PersonModule中的路径取决于它来自哪个应用程序/组件/链接?

1 个答案:

答案 0 :(得分:2)

花了一段时间来解决问题所在。但最后设法让它按你的意愿运作。

如果我理解你,那么EmployeesComponentStudentsComponent都需要使用mod-person-grid组件(本身有路由器插座),能够显示所选人员的详细信息。

第1步

为了能够实现上述目标,即在mod-person-grid组件的路由器插座中呈现人员的详细信息,该组件是Employees和{{1}模板的一部分组件是基本路由,呈现这些组件需要知道要呈现的任何子路由。这些是Students中定义的子路由,可以定义如下。

PersonsModule

以上基本上说const appRoutes: Routes = [ { path: '', redirectTo: '/home', pathMatch: 'full' }, { path: 'home', component: HomeComponent }, { path: 'employees', component: EmployeesComponent, loadChildren:'src/person.module.ts#PersonModule' }, { path: 'students', component: StudentsComponent, loadChildren:'src/person.module.ts#PersonModule' } ]; 路由将呈现employees(包含从EmployeesComponent获得的路由器插座)的内容,并且还具有子路由,通过mod-person-grid中定义的路由获取,必要时将延迟加载(通过PersonsModule实现)。

第2步

当加载应用程序时,它错误地也呈现了loadChildren的内容(这打破了整体内容)。之所以发生这种情况,是因为您在导入应用程序模块时导入了主路由配置和PersonGridComponent中定义的路由配置。

PersonsModule

这会在这两种配置之间产生冲突

路线1

@NgModule({
  imports: [ ..., RouterModule.forRoot(appRoutes), PersonModule.forRoot() ]
})
export class AppModule {}

路线2

const appRoutes: Routes = [
  { path: '',   redirectTo: '/home', pathMatch: 'full' },
  { path: 'home',  component: HomeComponent }
];

两者都声明空路径const personRoutes: Routes = [ { path: '', component: PersonGridComponent, children: [ ... ] } ]; 应该呈现''路由,通过路由1 中配置的重定向和home来实现在路线2 中配置。

此问题的修复是将路由2 的配置映射到指定的插座,如下所示

PersonsGridComponent

和处理重定向的const personRoutes: Routes = [ { path: '', component: PersonGridComponent, children: [ ... ], outlet: 'person' } ]; 中的部分,就像这样工作

PersonsGridComponent

详细了解指定商店here

第3步

最后一个修复涉及 <td><a [routerLink]="[{ outlets: { person: ['view', person.id]} }]">view</a></td> 中的错误配置。在PersonsModule的{​​{1}}重定向定义中,指定该链接必须为PersonGridComponent ...但是在您的路由定义中,您绑定了routerLink部分路线,到view/{id}

view

然后会破坏渲染。这不是您所需要的,而是您需要通过PersonGridComponent显示此人的详细信息。路线已更新如下

const personRoutes: Routes = [
  { 
     path: '', component: PersonGridComponent, // <- This here
     ...
  }
];

Plunker

我已经分叉了你的傻瓜,并解决了你的问题。您可以看到完整的解决方案here