webentwicklung-frage-antwort-db.com.de

Angular 2 neuer Router: Wie erhalte ich Router-Parameter einer untergeordneten Komponente?

In der neuesten Version von @angular/router3.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?

12
Vassilis Pits

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

23
Brandon

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.

5
Mark Rajcok
this.route.snapshot.paramMap.get('id');
0
labu4bd
  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
atjoshi

Mit this.activatedRoute.snapshot.firstChild.params

0
gildniy

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:

  • Die activatedRoute.firstChild-Eigenschaft ist eine ActivatedRoute-Instanz und NICHT eine beobachtbare Instanz.
  • Beachten Sie auch, dass activatedRoute.paramMap beobachtbar ist.

So können Sie auf Probleme stoßen:

  • Stellen Sie sich eine Komponente mit zwei untergeordneten Routen und entsprechenden Komponenten vor, bei der jeweils nur eine angezeigt wird (z. B. eine Oberfläche mit Registerkarten).
  • Wenn Sie auf 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.
  • Wenn Sie zur zweiten Registerkarte wechseln und dann zurück zur ersten Registerkarte, wird alles kaputt gehen. Dies liegt daran, dass Sie paramMap ursprünglich für eine ActivatedRoute-Instanz abonniert haben, die nicht mehr vorhanden ist.
  • Wichtig: Dies ist nur ein Problem, wenn Sie versuchen, auf die 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!

0
Simon_Weaver