Как служба может подписаться на параметр текущего маршрута?

#angular #router #angular-activatedroute

#angular #маршрутизатор #angular-activatedroute

Вопрос:

Я хотел бы создать службу, которая подписывается на изменения в параметре Angular. К сожалению, это, похоже, не работает.

 export class LocationResourcesService {

  constructor(private activatedRoute: ActivatedRoute) {

    this.activatedRoute.paramMap.pipe(
      map((params: ParamMap) => params.get('account-id')),
    ).subscribe((newValue) => console.log(newValue))
  }
  // ----------
}
 

Вышеуказанная подписка выдает только одно значение — при первой загрузке Angular на страницу. И это значение равно null . Та же подписка выполняется, когда она помещается в конструктор компонента, который активен на странице. предположительно, потому что маршрут загружен и ActivatedRoute задан.

Я бы предположил, что ActivatedRoute был одноэлементным сервисом и поэтому я мог подписаться на изменения в нем. Очевидно, что это не так, но как эта служба может подписаться на значение activatedRoute.ParamMap ?

Комментарии:

1. Правильно ли ваш маршрутизатор анализирует маршрут? попробуйте эту enableTracing опцию и посмотрите account-id , появляется ли параметр при переходе к соответствующему маршруту.

Ответ №1:

К сожалению, на этот вопрос нет простого ответа. Я не собираюсь воспроизводить все обсуждение, но решение можно увидеть здесь: https://github.com/angular/angular/issues/11023#issuecomment-399667101 .

И я копирую его, чтобы упростить его понимание. Как я уже сказал, это не просто:

 import { Injectable } from '@angular/core';
import { ActivatedRoute, Router, NavigationEnd, Params } from '@angular/router';
import { filter, switchMap } from 'rxjs/operators'
import { of, Observable } from 'rxjs'

@Injectable()
export class MiscService {

  params$: Observable<Params>

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

    // Create an observable representing the params
    this.params$ = this.router.events.pipe(
      filter(event => event instanceof NavigationEnd),
      switchMap(() => {
        const params = this.route.firstChild?.params
        // return params or an empty observable 
        return params || of()
      })
    )
    
    // subscribe to the params$ observable - can be done for 
    // multiple observers
    this.params$.subscribe((params) => {
      console.log('params', params)
    })
  }

}