@angular/router
3.0.0-rc.1
の最新バージョンでは、URL /ルートからパラメーターを取得する方法が変更されました。
this ドキュメンテーションに基づいて、paramsにサブスクライブすることでparamsを取得できるはずですが、私の場合は機能していないようです。
私が達成したいのは、子ルートから親コンポーネントにパラメータを取得することです。
たとえば、これが私のルートだとしましょう:
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);
});
}
}
このように私は得ています:
Undefined
ここに何が欠けていますか?
ActivatedRoute
には、その親/子ルート情報にアクセスするためのゲッターがあります。
親から最初の子ルートにアクセスするには、次を使用します。
this.route.firstChild.params
すべての子ルートが必要な場合は、children
プロパティを使用します。 ActivatedRoute
の配列を返します
this.route.children
子ルートにいて、親からのパラメーターが必要な場合:
this.route.parent.params
子パラメーターは、子と関連付け/保管されます ActivatedRoute 。親のActivatedRouteでは使用できません。したがって、最初にゲッターfirstChild
またはchildren
を使用して子のActivatedRouteを取得する必要があります。
次に、親は子パラメーターの変更をサブスクライブできます。
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.children
またはActivatedRouteSnapshot.children
を使用して、子ActivatedRoutesまたは子ActivatedRouteShapshotsの配列を取得します。
ActivatedRouteを使用して子パラメーターを取得するのは非常に簡単ですが、現在の子を変更すると、すぐに問題に遭遇する可能性があります。
最初にいくつかの注意事項:
activatedRoute.firstChild
プロパティはActivatedRoute
インスタンスであり、オブザーバブルではありません。activatedRoute.paramMap
は観察可能です。問題に直面する方法は次のとおりです。
ngOnInit
ハンドラー内でfirstChild.paramMap
にアクセスすると、それにサブスクライブして、パラメーターの変化を監視できます。これは見た目も動作も問題ありません。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
に相当するものがあるはずだと提案するかもしれませんが、これは問題にはなりません。ただし、他のシナリオではさらに混乱を招く可能性があります!
this.route.snapshot.paramMap.get('id');
this.activatedRoute.snapshot.firstChild.params
を使用して
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
});
}
});