Подпишитесь как на параметры маршрута, так и на queryParams в Angular 2

Я установил следующую систему маршрутизации

export const MyRoutes: Routes = [
    {path: '', redirectTo: 'new', pathMatch: 'full'},
    {path: ':type', component: MyComponent}
];

и иметь следующую навигационную систему

goToPage('new');
goToPageNo('new', 2);

goToPage(type) {
    this.router.navigate([type]);
}
goToPageNo(type, pageNo) {
    this.router.navigate([type], {queryParams: {page: pageNo}});
}

Пример URL выглядит следующим образом

http://localhost:3000/new

http://localhost:3000/new?page=2

http://localhost:3000/updated

http://localhost:3000/updated?page=5

Иногда у них есть необязательный queryParams (страница)

Теперь мне нужно прочитать как параметры маршрута, так и queryParams

ngOnInit(): void {
    this.paramsSubscription = this.route.params.subscribe((param: any) => {
        this.type = param['type'];
        this.querySubscription = this.route.queryParams.subscribe((queryParam: any) => {
            this.page = queryParam['page'];
            if (this.page)
                this.goToPageNo(this.type, this.page);
            else
                this.goToPage(this.type);
        });
    });
}

ngOnDestroy(): void {
    this.paramsSubscription.unsubscribe();
    this.querySubscription.unsubscribe();
}

Теперь это работает не так, как ожидалось, посещая страницы без queryParams, а затем я посещаю страницу с помощью queryParams. "goToPageNo" вызывается несколько раз, так как я подписываюсь на queryParams внутри параметров маршрута.

Я просмотрел документацию Angular 2, у них нет ни одного примера или кодов, где одновременно реализуется подписка на параметры маршрута и queryParams.

Любой способ сделать это правильно? Любые предложения?

Ответ 1

Для угловых 6+

import { combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';

...

combineLatest(this.route.params, this.route.queryParams)
    .pipe(map(results => ({params: results[0].xxx, query: results[1]})))
    .subscribe(results => {
        console.log(results);
    });

Где xxx от вашего маршрута

{path: 'post/:xxx', component: MyComponent},

Ответ 2

Мне удалось получить отдельную подписку на оба параметра: "Параметры запроса" и "Парамы", объединив наблюдаемые, используя Observable.combineLatest перед подпиской.

Eg.

var obsComb = Observable.combineLatest(this.route.params, this.route.queryParams, 
  (params, qparams) => ({ params, qparams }));

obsComb.subscribe( ap => {
  console.log(ap.params['type']);
  console.log(ap.qparams['page']);
});

Ответ 3

Поздний ответ, но другое решение: вместо подписки на params и queryparams я подписываюсь на событие NavigationEnd на маршрутизаторе. Запускается только один раз, и на снимке доступны как параметры, так и параметры запроса: (пример для angular 4)

this.router.events.filter(event=>event instanceof NavigationEnd)
   .subscribe(event=>{
       let yourparameter = this.activatedroute.snapshot.params.yourparameter;
       let yourqueryparameter = this.activatedroute.snapshot.queryParams.yourqueryparameter;
   });

Что касается отмены подписки: да, это правда, что параметры маршрутизации, queryParams или подписки на события навигации автоматически отписываются маршрутизатором, однако есть одно исключение: если у вашего маршрута есть дочерние элементы, при переходе между дочерними элементами отмена подписки не произойдет. Только когда вы уходите от родительского маршрута!

Например, у меня была ситуация с вкладками в качестве дочерних маршрутов. В конструкторе первой вкладки компонент подписывается на параметры маршрута для получения данных. Каждый раз, когда я перехожу с первой на вторую вкладку и обратно, добавлялась другая подписка, в результате чего количество запросов увеличивалось.

Ответ 4

Используйте ActivatedRouteSnapshot из ActivatedRoute

ActivatedRouteSnapshot интерфейс имеет свойство params и queryParams, и вы можете получить оба значения одновременно.

constructor(private route: ActivatedRoute) {
    console.log(this.route.snapshot.params);
    console.log(this.route.snapshot.queryParams);
}

Изменить: как указано OP, мы получаем только начальное значение параметров с помощью этой техники.

Пример Plunker

Ответ 5

Я думаю, что вы должны использовать почтовый оператор https://www.learnrxjs.io/operators/combination/zip.html

Потому что, если вы используете combLatest и меняете параметры URL или параметры запроса, вы получаете значение с помощью новых параметров запроса и старых параметров URL.

URL-адреса, например:

HTTP://локальный /1 value = 10

HTTP://локальный /2 value = 20

HTTP://локальный /3 value = 30