Angular 2 Activatedroute params не работает в сервисе или снаружи

у меня очень странная проблема: индекс.HTML-код

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

навигационное меню является компонентом навигационного меню. В контенте router-outlet есть компонент под названием "assets".

что я сделал в компоненте активов:

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

это работает, и я получаю параметры моего маршрута (который является своего рода "asset/:id).

теперь я попробовал то же самое в моем компоненте навигационного меню (который находится "вне" розетки маршрутизатора) и в глобальной службе под названием контекстсервис. Тот же код, что и выше, но он даже не запускается при изменении маршрута. Если я попытаюсь получить текущий снимок маршрутизатора

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

после запуска события NavigationEnd результат тот же: strId не определен, потому что params являются пустым объектом.

он работает только в моем компоненте активов. Работает ли это по назначению или как это следует обрабатывать?

моим намерением было вызвать событие из глобальной службы (или "глобального" компонента, такого как nav меню), который прослушивает все изменения маршрута(-params).

моим единственным решением было бы проанализировать полный url-адрес после каждого события NavigationEnd, которое, на мой взгляд, не является правильным...Или обрабатывать изменение параметров в каждом дочернем компоненте (в маршрутизаторе-розетке).

может, у меня просто основная ошибка в понимании...

спасибо

решение принято отвечать:

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

Не забудьте импортировать RoutesRecognized из угловой маршрутизатор!!

3 ответов


компонент, добавленный маршрутизатором, получает сегмент маршрутизатора (ActivatedRoute) прошло, но в сервисе нет активированного маршрута. Вы можете подписаться на маршрутизатор.события и пересечение дерева маршрутов (маршрутизатор.возвращение null...`) чтобы получить параметры из конкретного sequement маршрут вам необходим.

Смотрите также https://github.com/angular/angular/issues/11023


вот угловая служба, которая делает это:

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

        }

.


на самом деле, ваш activatedRoute является правильным и обновленным, но у вас есть все дерево в этом. так что если вы пройдете весь путь внутри маршрута.firstChild, Вы, наконец, найдете последний маршрут, который я назвал deeperActivatedRoute (внутри маршрута.возвращение null...маршрут.возвращение null)

Так что я сделал, это создать сервис для отслеживания deeperRoute, и он всегда доступен

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

потом в приложение.деталь.ts я запускаю службу (просто чтобы убедиться, что это всегда отслеживание)

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

и, наконец, возьмите свой маршрут, где бы вы ни находились:

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

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

отвечая на вопрос, вы можете просто взять deeperActivatedRoute и проверить обычно snapshop.url, как и в компоненте