Angular 2:在另一个组件上定义路由器而不是引导组件

Posted

技术标签:

【中文标题】Angular 2:在另一个组件上定义路由器而不是引导组件【英文标题】:Angular 2 : defining a Router on another Component than the bootstraped one 【发布时间】:2016-07-19 17:05:59 【问题描述】:

我仍在使用 Angular2 进行项目。 如果您想了解有关我为什么需要做我将要解释的事情的更多详细信息,请参阅issue。

我有一个AppComponent,它是通过bootstrap 引导的。这是一个非常简单的组件:

@Component(
    selector: 'app-view',
    directives: [ Devtools, MainComponent ],
    template: `
        <ngrx-devtools></ngrx-devtools>
        <main-cmp></main-cmp>
    `
)
export class AppComponent  

此组件包括另一个组件:MainComponent(通过 main-cmp 选择器)。由于某些原因,我想在MainComponent 中设置我的路由。

代码如下:

@Component( 
    selector: 'main-cmp',
    directives: [ ROUTER_DIRECTIVES, NavComponent ],
    template: `
        <h1>App</h1>
        <nav-cmp></nav-cmp>
        <router-outlet></router-outlet>
    `
)
@RouteConfig([
     path: '/home',    name: 'Home',   component: HomeComponent,   useAsDefault: true ,
     path: '/medias',  name: 'Medias', component: MediasComponent 
])
export class MainComponent 
    constructor (private router:Router, private store:Store<AppStore>) 
        router.subscribe(url => store.dispatch(changeUrl(url)));
    

最后,MainComponent 包括NavComponent,这是一个非常基本的导航。

问题是,通过这个设置,我遇到了这个问题: EXCEPTION: Component "AppComponent" has no route config. in [['Home'] in NavComponent@2:15].

当然,如果我将路由器的逻辑移动到AppComponent,一切正常。

所以我的问题是:有没有办法将东西路由到另一个组件而不是引导的组件?

谢谢:)。

【问题讨论】:

【参考方案1】:

这似乎是不可能的,因为RouteRegistry 类的generate 方法显式依赖(硬编码)根组件。在源代码中看到这一行:

https://github.com/angular/angular/blob/master/modules/angular2/src/router/route_registry.ts#L345

这是导致错误的代码:

RouteRegistry.prototype._generate = function(linkParams,
         ancestorInstructions, prevInstruction, _aux, _originalLink) 
  (...)
  var parentComponentType = this._rootComponent; // <----
  (...)

  var rules = this._rules.get(parentComponentType);
  if (lang_1.isBlank(rules))  // <----
    throw new exceptions_1.BaseException("Component \"" +
      lang_1.getTypeNameForDebugging(parentComponentType) +
      "\" has no route config.");
  

  (...)
;

此方法是从RouterLink 指令的_updateLink 方法间接使用的。

这是相应的堆栈跟踪:

RouteRegistry._generate (router.js:2702)
RouteRegistry.generate (router.js:2669)
Router.generate (router.js:3174)
RouterLink._updateLink (router.js:1205)

查看我用来调试问题的 plunkr:https://plnkr.co/edit/8JojtgZmc8kA9ib6zvKS?p=preview。

【讨论】:

【参考方案2】:

解决方法怎么样 - 使用 root 作为子路由?

@Component(
  selector: 'app',
  directives: [ ROUTER_DIRECTIVES ],
  template: `
    <router-outlet></router-outlet>
  `
)
@RouteConfig([
  path: '/...', as: 'Main', component: MainComponent, useAsDefault: true 
])
export class App  

@Component( 
    selector: 'main-cmp',
    directives: [ ROUTER_DIRECTIVES ],
    template: `
        <h1>App</h1>
        <router-outlet></router-outlet>
    `
)
@RouteConfig([
     path: '/home',    name: 'Home',   component: HomeComponent,   useAsDefault: true ,
])
export class MainComponent  

【讨论】:

以上是关于Angular 2:在另一个组件上定义路由器而不是引导组件的主要内容,如果未能解决你的问题,请参考以下文章

Angular 路由器附加组件数据而不是替换组件

如何使用 react-router-dom 卸载路由更改上的组件而不是重新渲染 [重复]

如何在另一个模块/路由器中使用组件

如何在另一个模块/路由器中使用组件

Angular 5:从组件生成 DIV 而不是新标签

Angular 5:从组件生成 DIV 而不是新标签