In der neuesten Version von @angular/router
3.0.0-rc.1
Die Art und Weise, wie Sie die Parameter von einer URL/Route erhalten, wurde geändert.
Basierend auf this documentation sollten Sie in der Lage sein, die Parameter durch das Abonnieren der Parameter zu erhalten, aber in meinem Fall scheint das nicht zu funktionieren.
Was ich erreichen möchte, ist, Params von untergeordneten Routen in meine übergeordnete Komponente zu bringen.
Nehmen wir zum Beispiel an, dass dies meine Routen sind:
const routes: Routes = [
{
path: 'parent',
component: ParentComponent,
pathMatch: 'prefix',
children: [
{
path: ':id',
component: ChildComponent
}
]
}
];
Ich möchte den Parameter id
abrufen und ihn in meiner ParentComponent verwenden. So probiere ich Folgendes aus:
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);
});
}
}
So bekomme ich:
Undefined
Was fehlt mir hier?
Die Variable ActivatedRoute
verfügt über Getter, um auf die Informationen ihrer übergeordneten und untergeordneten Route zuzugreifen.
Für den Zugriff auf die erste untergeordnete Route vom übergeordneten Element würden Sie Folgendes verwenden:
this.route.firstChild.params
Wenn Sie alle untergeordneten Routen wünschen, verwenden Sie die children
-Eigenschaft. Dies gibt ein Array von ActivatedRoute
zurück.
this.route.children
Wenn Sie sich in einer untergeordneten Route befanden und Parameter vom übergeordneten Element benötigten:
this.route.parent.params
Die untergeordneten Parameter werden mit dem untergeordneten ActivatedRoute verknüpft/gespeichert. Sie sind nicht in ActivatedRoute des übergeordneten Objekts verfügbar. Sie müssen also zuerst die ActivatedRoute des Kindes mit dem Getter firstChild
oder children
abrufen.
Dann kann das übergeordnete Element untergeordnete Parameteränderungen abonnieren:
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();
}
}
oder es kann eine Momentaufnahme der untergeordneten Parameter abgerufen werden:
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);
}
}
Wenn Sie alle untergeordneten Objekte abrufen möchten (z. B. mehrere Outlets), verwenden Sie ActivatedRoute.children
oder ActivatedRouteSnapshot.children
, um ein Array von untergeordneten ActivatedRoutes oder untergeordneten ActivatedRouteShapshots abzurufen.
this.route.snapshot.paramMap.get('id');
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
});
}
});
Mit this.activatedRoute.snapshot.firstChild.params
Es ist sehr einfach, die untergeordneten Parameter über ActivatedRoute abzurufen. Sie können jedoch schnell Probleme bekommen, wenn Sie das aktuelle untergeordnete Element ändern.
Zuerst ein paar Notizen:
activatedRoute.firstChild
-Eigenschaft ist eine ActivatedRoute
-Instanz und NICHT eine beobachtbare Instanz.activatedRoute.paramMap
beobachtbar ist.So können Sie auf Probleme stoßen:
firstChild.paramMap
in Ihrem ngOnInit
-Handler zugreifen, können Sie ihn abonnieren und die Parameter überwachen, wenn sie sich ändern. Das wird gut aussehen und funktionieren.paramMap
ursprünglich für eine ActivatedRoute-Instanz abonniert haben, die nicht mehr vorhanden ist.paramMap
des Kindes zuzugreifen. Wenn Sie versuchen, auf Ihre "eigene" paramMap zuzugreifen, oder die untergeordnete Komponente auch paramMap
injiziert, ist alles in Ordnung.Die sauberste Lösung, die ich gefunden habe, lautet wie folgt:
Hinweis: Fügen Sie neben router: Router
zuerst route: ActivatedRoute
ein.
const firstChildParams$ = this.router.events.pipe(filter(e => e instanceof NavigationEnd),
startWith(undefined),
switchMap(e => this.route.firstChild!.paramMap));
Was dies tut, ist nur für NavigationEnd-Ereignisse zu hören, nach denen eine neue firstChild
verfügbar ist. Wenn Sie switchMap
verwenden, müssen Sie sich keine Sorgen darüber machen, dass Sie alte redundante Karten abbestellen müssen. Auch nicht, dass der tatsächliche Wert des Navigationsereignisses niemals verwendet wird und startWith
erforderlich ist, um Parameter sofort beim ersten Mal verarbeiten zu können.
Ich habe hilfreiche Dinge wie diese in einem RouterHelperService gesammelt, den ich überall injizieren kann und mich nicht an all diese Verrücktheit erinnern muss.
Eines Tages kann ich vorschlagen, dass es ein beobachtbares Äquivalent von firstChild
geben sollte, dann wäre dies kein Problem. In anderen Szenarien könnte dies jedoch noch mehr Verwirrung stiften!