wake-up-neo.net

Angular 2 Activatedroute-Parameter funktionieren nicht im Service oder außerhalb von <Router-Outlet>

Ich habe ein sehr seltsames Problem: Index.html

<navigation-menu *ngIf="isLoggedIn"></navigation-menu>
<div class="content-wrapper" [ngClass]="{'fullContent' : !isLoggedIn}">
    <section class="content">
        <router-outlet></router-outlet>            
    </section>
</div>

Das Navigationsmenü ist eine Komponente für das Navigationsmenü . Im Inhalt der Router-Outlets gibt es eine Komponente namens "Assets". 

Was ich in der Assetkomponente gemacht habe:

import { ActivatedRoute}from "@angular/router";
constructor(private route: ActivatedRoute){}
public ngOnInit(): void {
    this.route.params.subscribe(params => {
        const id = params["id"];
}

Das funktioniert und ich bekomme die Parameter meiner Route (was eine Art "asset /: id" ist).

Jetzt habe ich dasselbe in meiner Navigations-Menü-Komponente (die sich außerhalb des Router-Steckplatzes befindet) und in einem globalen Dienst namens Contextservice ..__ ausprobiert. Wenn ich versuche, einen aktuellen Router-Schnappschuss zu erhalten 

  const strId = this.route.snapshot.params["id"];

nachdem das Ereignis NavigationEnd ausgelöst wurde, ist es dasselbe Ergebnis: StrId ist undefiniert, da Params ein leeres Objekt sind.

Es funktioniert nur in meiner Assetkomponente ..__ Funktioniert dies wie beabsichtigt oder wie sollte damit verfahren werden? 

Mein Ziel war es, ein Ereignis von einem globalen Dienst (oder einer "globalen" Komponente wie dem Nav-Menü) auszulösen, der alle Routenänderungen (-params) abhört. 

Meine einzige Lösung wäre, die komplette URL nach jedem NavigationEnd-Ereignis zu analysieren, was meiner Meinung nach kein richtiger Weg ist ... oder die Änderung der Parameter in jeder untergeordneten Komponente (im Router-Ausgang) selbst zu behandeln.

Vielleicht habe ich nur einen grundlegenden Fehler im Verständnis ...

Vielen Dank

Lösung aus akzeptierter Antwort:

this.router.events.subscribe(val => {
        if (val instanceof RoutesRecognized) {
            var strId = val.state.root.firstChild.params["id"];
        }});

Vergessen Sie nicht, vom Winkelrouter erkannte Routen zu importieren !!

18
Cabe Skuriles

Die vom Router hinzugefügte Komponente erhält das Routersegment (ActivatedRoute), aber in einem Dienst gibt es keine aktivierte Route. Sie können router.events abonnieren und den Routenbaum durchlaufen (router.firstChild ... `), um Parameter aus einer bestimmten Routensequenz herauszufinden, die Sie benötigen.

Siehe auch https://github.com/angular/angular/issues/11023

18

Hier ist ein Winkeldienst, der das tut: 

import {Injectable}                                                        from '@angular/core';
import {ActivatedRoute, NavigationEnd, NavigationExtras, ParamMap, Router} from "@angular/router";
import {RouterExtensions}                                                  from "nativescript-angular/router";
import {NavigationOptions}                                                 from "nativescript-angular/router/ns-location-strategy";
import {Observable}                                                        from "rxjs/Observable";
import {first}                                                             from "rxjs/operators/first";
import {filter}                                                            from "rxjs/operators/filter";
import {map}                                                               from "rxjs/operators/map";
import {switchMap}                                                         from "rxjs/operators/switchMap";
import {unRegisterAndroidOnBack}                                           from "../../utils/view.utils";

@Injectable()
export class RoutingService
    {
        constructor(private routerExtensions: RouterExtensions, private route: ActivatedRoute, private router: Router)
        {
        }
        public getActivatedRouteParameter(paramName: string): Observable<ParamMap>
        {
            return this.router.events.pipe(filter(e => e instanceof NavigationEnd),
                                           map((): ActivatedRoute =>
                                               {
                                                   let route = this.route;
                                                   while (route.firstChild)
                                                       {
                                                           route = route.firstChild;
                                                       }
                                                   return route;
                                               }),
                                           filter((route: ActivatedRoute) => route.outlet === 'primary'),
                                           switchMap((route: ActivatedRoute) => route.paramMap) , first());

        }

.

1
Royi Namir

Eigentlich ist Ihre aktivierte Route korrekt und aktualisiert, aber Sie haben alle Baumstrukturen darin. Wenn Sie also den ganzen Weg innerhalb von route.firstChild gehen, finden Sie schließlich die letzte Route, die ich deeperActivatedRoute genannt habe (innerhalb von route.firstChild ... route.firstChild)

Ich habe also einen Dienst erstellt, um die deeperRoute zu verfolgen und jederzeit verfügbar zu haben 

import { Injectable } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';

@Injectable()
export class ActivatedRouteService {
  private _deeperActivatedRoute: ActivatedRoute;
  get deeperActivatedRoute(): ActivatedRoute {
    return this._deeperActivatedRoute;
  }

  constructor(private router: Router, private route: ActivatedRoute) {}

  init(): void {
    this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        // Traverse the active route tree
        let activatedChild = this.route.firstChild;
        if (activatedChild != null) {
          let nextActivatedChild;
          while (nextActivatedChild != null) {
            nextActivatedChild = activatedChild.firstChild;
            if (nextActivatedChild != null) {
              activatedChild = activatedChild.firstChild;
            }
          }
        }

        this._deeperActivatedRoute = activatedChild || this.route;
      }
    });
  }
}

Dann starte ich in app.component.ts den Dienst (um sicherzustellen, dass er immer verfolgt wird)

export class AppComponent {
  constructor(private activatedRouteService: ActivatedRouteService) {
    this.activatedRouteService.init();
  }
}

Und schließlich nehmen Sie Ihre Route überall dort, wo Sie sich befinden:

export class ForbiddenInterceptor implements HttpInterceptor {
  constructor(private activatedRouteService: ActivatedRouteService) { }

  doYourStuff(): void {
       //you'll have the correct activatedRoute here
       this.activatedRouteService.deeperActivatedRoute;
  }
}

Wenn Sie die Frage beantworten, können Sie einfach die deeperActivatedRoute nehmen und normalerweise die Datei snapshop.url überprüfen, genau wie in einer Komponente

0
LuizAsFight