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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/38956129/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:45:04  来源:igfitidea点击:

Angular 2 new Router: How to get router parameters of a child component?

angulartypescriptrxjsangular2-routing

提问by Vassilis Pits

In the latest version of @angular/router3.0.0-rc.1The way you get the parameters from a URL/route changed.

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

Based on thisdocumentation you should be able to get the params by subscribing to the params but in my case it seems that is not working.

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

What I want to achieve is to get params into my parent component FROM child routes.

我想要实现的是将参数从子路由中获取到我的父组件中。

For example let's say this is my routes:

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

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

I want to get the idparameter and use it in my ParentComponent. So I'm trying like this:

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

  }

}

Like this I'm getting:

像这样我得到:

Undefined

不明确的

What am I missing here?

我在这里错过了什么?

回答by Brandon

The ActivatedRoutehas getters to access its parent/child route information.

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

In order to access the first child route from the parent, you would use:

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

this.route.firstChild.params

this.route.firstChild.params

If you wanted all the child routes you would use the childrenproperty. This returns an array of ActivatedRoute

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

this.route.children

this.route.children

If you were in a child route and needed parameters from the parent:

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

this.route.parent.params

this.route.parent.params

回答by Simon_Weaver

It's super easy to get the child parameters via ActivatedRoute, however you can quickly run into issues if you change the current child.

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

First a couple notes:

首先要注意几点:

  • activatedRoute.firstChildproperty is an ActivatedRouteinstance and NOT an observable.
  • Also note that activatedRoute.paramMapis an observable.
  • activatedRoute.firstChild属性是一个ActivatedRoute实例,而不是一个可观察的。
  • 另请注意,这activatedRoute.paramMap是一个可观察的。

Here's how you can run into problems:

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

  • Consider a component with two child routes - and corresponding components - where only one is shown at a time (for example a tabbed interface).
  • If you access firstChild.paramMapinside your ngOnInithandler you'll be able to subscribe to it and monitor the parameters as they change. This will look and work just fine.
  • If you switch to the second tab and then back to the first everything will break. This is because you originally subscribed paramMapon an ActivatedRoute instance that doesn't exist anymore.
  • Important: This is only a problem if you're trying to access the child's paramMap. If you're trying to access your 'own' paramMap, or the child component also injects paramMapthen everything will be fine.
  • 考虑一个具有两个子路由的组件 - 以及相应的组件 - 一次只显示一个(例如选项卡式界面)。
  • 如果您firstChild.paramMapngOnInit处理程序内部访问,您将能够订阅它并在参数更改时监视参数。这看起来和工作得很好。
  • 如果您切换到第二个选项卡,然后又回到第一个选项卡,一切都会中断。这是因为您最初订阅paramMap了一个不再存在的 ActivatedRoute 实例。
  • 重要提示:这仅在您尝试访问孩子的paramMap. 如果您尝试访问“自己的”paramMap,或者子组件也注入,paramMap那么一切都会好起来的。

The cleanest solution to this I've found is as follows:

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

Note: First inject router: Routerin addition to route: ActivatedRoute.

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

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

What this does is listens for only NavigationEnd events, after which a new firstChildwill be available. By using switchMapyou don't need to worry about unsubscribing to old redundant maps. Also not that the actual value of the navigation event is never used, and startWithis needed to be able to immediately handle parameters the first time.

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

I've been collecting helpful things like this into a RouterHelperService that I can inject anywhere, and not have to remember all this craziness.

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



Some day I may suggest that there should be an observable equivalent of firstChild, then this wouldn't be a problem. However it would perhaps introduce even more confusion in other scenarios!

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

回答by Mark Rajcok

The child parameters are associated/stored with the child ActivatedRoute. They are not available on the parent's ActivatedRoute. So you first need to get the child's ActivatedRoute using getter firstChildor children.

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

Then, the parent can either subscribe to child parameter changes:

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

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

or it can get a snapshot of the child parameters:

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

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

If you want to get all of the children (e.g., if you have multiple outlets), use ActivatedRoute.childrenor ActivatedRouteSnapshot.childrento get an array of child ActivatedRoutes or child ActivatedRouteShapshots.

如果您想获取所有子项(例如,如果您有多个出口),请使用ActivatedRoute.childrenActivatedRouteSnapshot.children获取子 ActivatedRoutes 或子 ActivatedRouteShapshots 的数组。

回答by gildniy

By using this.activatedRoute.snapshot.firstChild.params

通过使用 this.activatedRoute.snapshot.firstChild.params

回答by labu4bd

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

回答by Mr AJ

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