Angular 2新路由器:如何获取子组件的路由器参数?

Vas*_*its 14 rxjs typescript angular2-routing angular

在最新版本的@angular/router 3.0.0-rc.1The way中,您可以更改URL /路由中的参数.

根据这个文档,您应该能够通过订阅参数获得参数,但在我的情况下,它似乎不起作用.

我想要实现的是将params放入我的父组件FROM子路由.

例如,假设这是我的路线:

const routes: Routes = [
  {
    path: 'parent',
    component: ParentComponent,
    pathMatch: 'prefix',
    children: [
      {
        path: ':id',
        component: ChildComponent
      }
    ]
  }
];
Run Code Online (Sandbox Code Playgroud)

我想获取id参数并在我的ParentComponent中使用它.所以我这样做:

export class ParentComponent implements OnInit {

  sub: any;
  constructor(
    private route: ActivatedRoute) {
    this.route = route;
   }

  ngOnInit() {

    this.sub = this.route.params.subscribe(params => {
     let id = params['id'];
     console.log(id);
   });

  }

}
Run Code Online (Sandbox Code Playgroud)

像这样我得到:

未定义

我在这里错过了什么?

小智 27

该ActivatedRoute有干将访问它的父/子路由信息.

要从父级访问第一个子路由,您将使用:

this.route.firstChild.params

如果您想要所有子路线,您将使用该children属性.这将返回一个数组ActivatedRoute

this.route.children

如果您在子路线中并且需要来自父母的参数:

this.route.parent.params


Sim*_*ver 10

通过 ActivatedRoute 获取子参数非常容易,但是如果您更改当前子参数,您很快就会遇到问题。

首先要注意几点:

  • activatedRoute.firstChild属性是一个ActivatedRoute实例,而不是一个可观察的。
  • 另请注意,这activatedRoute.paramMap是一个可观察的。

以下是您遇到问题的方法:

  • 考虑一个具有两个子路由的组件 - 以及相应的组件 - 一次只显示一个(例如选项卡式界面)。
  • 如果您firstChild.paramMap在ngOnInit处理程序内部访问,您将能够订阅它并在参数更改时监视参数。这看起来和工作得很好。
  • 如果您切换到第二个选项卡,然后又回到第一个选项卡,一切都会中断。这是因为您最初订阅paramMap了一个不再存在的 ActivatedRoute 实例。
  • 重要提示:这仅在您尝试访问孩子的paramMap. 如果您尝试访问“自己的”paramMap,或者子组件也注入,paramMap那么一切都会好起来的。

我发现的最干净的解决方案如下:

注意:router: Router除了route: ActivatedRoute.

const firstChildParams$ = this.router.events.pipe(filter(e => e instanceof NavigationEnd),
                                                  startWith(undefined),
                                                  switchMap(e => this.route.firstChild!.paramMap));
Run Code Online (Sandbox Code Playgroud)

这样做是只侦听 NavigationEnd 事件,之后将有一个新事件firstChild可用。通过使用,switchMap您无需担心取消订阅旧的冗余地图。也不是导航事件的实际值从未使用过,并且startWith需要能够在第一次立即处理参数。

我一直在收集像这样有用的东西到 RouterHelperService 中,我可以在任何地方注入它,而不必记住所有这些疯狂。


有一天我可能会建议应该有一个可观察的等价物firstChild,那么这就不成问题了。然而,它可能会在其他场景中引入更多的混乱!


Mar*_*cok 5

子参数与子ActivatedRoute关联/存储.它们在父级的ActivatedRoute上不可用.因此,您首先需要使用getter firstChild或者获取孩子的ActivatedRoute children.

然后,父级可以订阅子参数更改:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute }               from '@angular/router';
import { Subscription }                 from 'rxjs/Subscription';

export class ParentComponent implements OnInit, OnDestroy {
   private sub: Subscription;
   constructor(private route: ActivatedRoute) {}
   ngOnInit() {
      this.sub = this.route.firstChild.params.subscribe(
        params => console.log(params.id));
   }
   ngOnDestroy() {
      this.sub.unsubscribe();
   }
}
Run Code Online (Sandbox Code Playgroud)

或者它可以获取子参数的快照:

import { Component }      from '@angular/core';
import { ActivatedRoute } from '@angular/router';

export class ParentComponent {
   constructor(private route: ActivatedRoute) {}
   someMethod() {
      console.log(this.route.firstChild.snapshot.params.id);
   }
}
Run Code Online (Sandbox Code Playgroud)

如果你想得到所有孩子(例如,如果你有多个出口),请使用ActivatedRoute.children或ActivatedRouteSnapshot.children获取一系列子ActivatedRoutes或子ActivatedRouteShapshots.