Angular 2:如何将路由参数传递给子路由?

时间:2016-05-24 02:44:50

标签: typescript routing angular

使用Angular 2 rc.1和TypeScript。当组件加载到子路由中时,我在将路由参数传递给组件时遇到了很多麻烦。我使用@angular/router-deprecated包。

在我的根组件中,我按如下方式配置了路由:

@RouteConfig([
  {path:'/top', name:'Top', component: EndPointComponent},
  {path:'/sub/...', name:'Sub', component: MiddleManComponent}
])

这是端点组件,我尝试读取参数

import {Component} from '@angular/core';
import {RouteParams} from '@angular/router-deprecated';
@Component({
    template: 'Route Params: {{routeParams.params | json}}'
})
export class EndPointComponent{
    constructor(private routeParams:RouteParams){}
}

以下是中间人组件,其子路由到EndPointComponent

import {Component} from '@angular/core';
import {RouteConfig, ROUTER_DIRECTIVES} from '@angular/router-deprecated';
import {EndPointComponent} from "./endpoint.component";

@Component({
    directives: [ROUTER_DIRECTIVES]
    template: `<router-outlet></router-outlet>`
})
@RouteConfig([
    {path: '/end', name: 'End', component: EndPointComponent, useAsDefault: true}
])
export class MiddleManComponent {}

当从顶级路由加载组件时,可以从routeParams EndPointComponent对象成功读取参数(例如:根组件中名为'Top'的路由)。但是,当我通过EndPointComponent导航到MiddleManComponent时,参数始终为空(例如:通过根组件中名为“Sub”的路径)。

子路由器在解析路由之前是否擦除了父节点中的参数?这没有多大意义所以我打赌我错过了一些东西。我的问题很简单:如何将路由参数传递给子路由?

PS:我试图为demo this setup构建一个plunker但是当我无法弄清楚应用程序无法加载的原因时我放弃了。

4 个答案:

答案 0 :(得分:4)

子路由实际上获得了自己的RouteParams实例,与父路由不同。这样做是为了避免命名冲突并促进路由组件的封装。

您可以通过服务与子路由加载的组件共享父路由参数的一种方法。

@Injectable()
export class RouteParamService {
  constructor(private routeParams: RouteParams) {}

  get params() {
    return this.routeParams.params;
  }
}

@Component({
    template: 'Route Params: {{routeParams.params | json}}'
})
export class EndPointComponent{
    constructor(private routeParams:RouteParamService){}
}

@Component({
  directives: [ROUTER_DIRECTIVES]
  template: `<router-outlet></router-outlet>`,
  providers: [RouteParamService]
})
@RouteConfig([
  {path: '/end', name: 'End', component: EndPointComponent, useAsDefault: true}
])
class MiddleManComponent() { }

RouteParamService将在与MiddleManComponent相同的路由级别实例化,因此将获得相同的RouteParams实例。当您的服务被注入您的子路由组件时,您将能够访问父路由参数。

如果你需要在不同的路由树级别加载2个EndPointComponent实例,我认为你需要另一层父路由;即在RootComponent之间封装MiddleManComponent和EndPointComponent的路由组件。

RootComponent未路由,因此您无法从中为RouteParamService实例化RouteParams。 RouteParams由<router-outlet>组件提供。

答案 1 :(得分:3)

使用@angular/router@3.4.7,您可以使用

访问父ActivatedRoute
export class ChildComponent implements OnInit {

  parentRouteId: string;

  constructor(private route: ActivatedRoute) {
  }

  ngOnInit() {
    this.route.parent.params
      .subscribe((params: Params) => this.parentRouteId = params['id']);
  }
}

答案 2 :(得分:1)

使用&#34; @ angular / router&#34;:&#34; 3.0.0-alpha.6&#34;包,我能够通过执行以下操作获取父路由参数:

export class ChildComponent {

    private sub: any;

    private parentRouteId: number;

    constructor(
        private router: Router,
        private route: ActivatedRoute) {
    }

    ngOnInit() {
        this.sub = this.router.routerState.parent(this.route).params.subscribe(params => {
            this.parentRouteId = +params["id"];
        });
    }

    ngOnDestroy() {
        this.sub.unsubscribe();
    }
}

在此示例中,路线具有以下格式:/parent/:id/child/:childid

export const routes: RouterConfig = [
    {
        path: '/parent/:id',
        component: ParentComponent,
        children: [
            { path: '/child/:childid', component: ChildComponent }]
    }
];

答案 3 :(得分:0)

您可以注入ActivatedRote并拍摄快照,甚至更轻松:

constructor(private route: ActivatedRoute) {}; ngOnInit() { console.log('one of my parents route param:', this.route.snapshot.parent.params['PARAM-NAME']); }