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

时间:2016-08-15 13:36:35

标签: angular typescript rxjs angular2-routing

在最新版本的@angular/router 3.0.0-rc.1中,您从网址/路线获取参数的方式发生了变化。

基于this文档,您应该能够通过订阅参数来获取参数,但在我的情况下,它似乎无效。

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

例如,让我们说这是我的路线:

const routes: Routes = [
  {
    path: 'parent',
    component: ParentComponent,
    pathMatch: 'prefix',
    children: [
      {
        path: ':id',
        component: ChildComponent
      }
    ]
  }
];

我想获取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);
   });

  }

}

像我这样:

  

未定义

我在这里缺少什么?

5 个答案:

答案 0 :(得分:25)

ActivatedRoute有getter访问其父/子路由信息。

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

this.route.firstChild.params

如果您想要所有子路线,请使用children属性。这将返回一个ActivatedRoute

数组

this.route.children

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

this.route.parent.params

答案 1 :(得分:1)

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

首先要注意以下几点:

  • activatedRoute.firstChild属性是ActivatedRoute实例,不是可观察的。
  • 还请注意,activatedRoute.paramMap是可观察的。

这是您遇到问题的方法:

  • 考虑一个具有两个子路径的组件-以及相应的组件-一次仅显示一个子路由(例如选项卡式界面)。
  • 如果您在firstChild.paramMap处理程序中访问ngOnInit,则可以订阅它并监视其更改的参数。这样看起来和可以正常工作。
  • 如果您切换到第二个选项卡,然后又回到第一选项卡,则一切都会中断。这是因为您最初在一个已不存在的ActivatedRoute实例上订阅了paramMap
  • 重要提示:仅当您尝试访问孩子的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));

此操作仅侦听NavigationEnd事件,此后将提供新的firstChild。通过使用switchMap,您不必担心取消订阅旧的冗余映射。也不是永远不会使用导航事件的实际值,并且需要startWith才能在第一时间立即处理参数。

我一直在将类似这样的有用信息收集到RouterHelperService中,可以将其注入到任何地方,而不必记住所有这些疯狂行为。


总有一天,我可能建议应该有一个firstChild的等效值,这样就不成问题了。但是,在其他情况下,这可能会带来更多的混乱!

答案 2 :(得分:0)

使用this.activatedRoute.snapshot.firstChild.params

答案 3 :(得分:0)

  this.router.events.subscribe(event => {
            if (event instanceof RoutesRecognized) {
                // let strId = event.state.root.firstChild.children[0].data;
                let a = event.state.root.firstChild.children.map((route) => {
                    while (route.firstChild) {
                        route = route.firstChild;
                    }

                    return route;
                });
                console.log('Title', a[0].data.title);
                this.meta.updateTitle(a[0].data.title);
            }
            if (event instanceof NavigationEnd) {
                (<any>window).gtag('config', this.googleAnalyticsCode, {
                    'page_title' : this.titleService.getTitle(),
                    'page_path': event.urlAfterRedirects
                });
            }
        });

答案 4 :(得分:0)

this.route.snapshot.paramMap.get('id');