关于javascript:angular2:在另一个组件上定义一个路由器,而不是引导的组件

Angular 2 : defining a Router on another Component than the bootstraped one

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

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

1
2
3
4
5
6
7
8
9
@Component({
    selector: 'app-view',
    directives: [ Devtools, MainComponent ],
    template: `
        <ngrx-devtools></ngrx-devtools>
        <main-cmp></main-cmp>
    `
})
export class AppComponent { }

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

中设置路由。

这里是代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Component({
    selector: 'main-cmp',
    directives: [ ROUTER_DIRECTIVES, NavComponent ],
    template: `
        App
        <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,则一切正常。

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

谢谢:)。


这似乎是不可能的,因为RouteRegistry类的generate方法明确依赖于(硬编码)根组件。参见源代码中的这一行:

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

以下是解决错误的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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方法间接使用。

这是对应的堆栈跟踪:

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

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


一种解决方法-将root用作子路由?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@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: `
        App
        <router-outlet></router-outlet>
    `
})
@RouteConfig([
    { path: '/home',    name: 'Home',   component: HomeComponent,   useAsDefault: true },
])
export class MainComponent { }