首页 文章

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

提问于
浏览
12

在最新版本的 @angular/router 3.0.0-rc.1 中,您从URL /路由获取参数的方式已更改 .

基于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);
   });

  }

}

像这样我得到:

未定义

我在这里错过了什么?

6 回答

  • 0

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

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

    this.route.firstChild.params

    如果您想要所有子路由,您将使用 children 属性 . 这将返回 ActivatedRoute 的数组

    this.route.children

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

    this.route.parent.params

  • 0

    子参数与子项ActivatedRoute关联/存储 . 它们在父's ActivatedRoute. So you first need to get the child'的ActivatedRoute上不可用,使用getter firstChildchildren .

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

    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();
       }
    }
    

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

    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);
       }
    }
    

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

  • 0

    使用 this.activatedRoute.snapshot.firstChild.params

  • 5
    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
                    });
                }
            });
    
  • 0
    this.route.snapshot.paramMap.get('id');
    
  • 24

    通过ActivatedRoute获取子参数非常容易,但是如果更改当前子项,则可以快速遇到问题 .

    首先是几个笔记:

    • activatedRoute.firstChild 属性是 ActivatedRoute 实例,而不是可观察的 .

    • 另请注意 activatedRoute.paramMap 是可观察的 .

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

    • 考虑具有两个子路由的组件 - 以及相应的组件 - 其中一次只显示一个(例如选项卡式界面) .

    • 如果您在 ngOnInit 处理程序中访问 firstChild.paramMap ,您将能够订阅它并在更改时监视参数 . 这看起来和工作都很好 .

    • 如果切换到第二个选项卡然后回到第一个选项卡将会中断 . 这是因为您最初在不再存在的ActivatedRoute实例上订阅了 paramMap .

    • 重要提示:如果你're trying to access the child' s paramMap ,这只是一个问题 . 如果你're trying to access your '拥有'paramMap,或者子组件也注入 paramMap 那么一切都会好的 .

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

    注意:除 route: ActivatedRoute 外,首先注入 router: Router .

    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 ,那么这不会是个问题 . 然而,它可能会在其他场景中引入更多混乱!

相关问题