Лучшая практика извлечения параметров и queryParams в Angular 2
Я пытаюсь понять способ создания маршрута, с некоторой информацией в нем параметры URL.
Это мой маршрут (app.routes.ts):
{path: 'results/:id', component: MyResultsComponent},
Вот как я перемещаюсь по маршруту:
goToResultsPage(query: string) {
this.router.navigate(['results', query], { queryParams: { pageSize: 20 } });}
Как вы можете видеть, у меня также есть параметр запроса. Мне было интересно, какой лучший и самый чистый способ получить это в моем MyResultsComponent
. Прямо сейчас у меня есть вложенная структура subscribe
:
ngOnInit() {
this.route
.params
.subscribe(params => {
this.query = params['id'];
this.route
.queryParams
.subscribe(queryParams => {
this.offset = queryParams['pageSize'];
#find entries this.entryService.findEntries(this.query, this.pageSize);
});
});
}
Затем я хочу передать эти параметры в мой EntryService
, который возвращает найденные записи.
Ответы
Ответ 1
Как насчет использования forkJoin?
ForkJoin позволяет вам присоединиться к двум наблюдаемым и ждать ответа обоих. Вы можете увидеть документацию здесь и подробнее об этом здесь.
Что касается вашего кода, он будет выглядеть примерно так:
ngOnInit() {
Observable.forkJoin(this.route.params, this.route.queryParams).subscribe(bothParams => {
// bothParams is an array, on the first index we have the router.params
// on the second index we have the queryParams
this.query = bothParams[0].query;
this.pageSize = bothParams[0].pageSize;
this.entryService.findEntries(this.query, this.pageSize);
});
}
Вам может потребоваться добавить импорт:
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';
Ответ 2
Observable.combineLatest - это решение в этой ситуации, не так ли?
Observable
.combineLatest(
this.route.params,
this.route.queryParams,
(params: any, queryParams: any) => {
return {
id: +params.id,
pageSize: queryParams.pageSize ? +queryParams.pageSize: null
}
})
.subscribe(bothParams => {
this.id = bothParams.id;
this.pageSize = bothParams.pageSize;
});
Ответ 3
Я думаю, если вам нужно получить доступ к обоим одновременно, снимок - лучший вариант.
Не тестировался (только с верхушки головы)
ngOnInit() {
this.route
.params
.subscribe(params => {
this.query = params['id'];
this.offset = this.route.snapshot.queryParams['pageSize'];
# find entries this.entryService.findEntries(this.query, this.pageSize);
});
});
}
Ответ 4
Недавно я столкнулся с этой дилеммой, и лучшее решение, удовлетворяющее моим потребностям, которое я нашел, - это использовать Observable.merge
.
Использование моментального снимка не очень хорошо, если вы хотите смотреть изменения из params queryParams внутри одного и того же компонента (например, поиск с фильтрами).
Observable.forkJoin
имеет ограничение на то, что оба наблюдаемых должны запускаться, чтобы работать, поэтому, если у вас есть сценарий, в котором могут быть изменения в параметрах или в параметрах queryParams, но необязательно в обоих случаях, forkJoin не будет использовать вас.
Observable.merge
, с другой стороны, запускается при срабатывании любого из них. Конечно, это также имеет некоторые недостатки, так как вы можете иметь два обратных вызова, вызываемых один за другим (в начале с параметрами и queryParams).
Вот пример:
Observable.merge(
this.route.params.map(params => this.handleParams(params)),
this.route.queryParams.map(queryParams => this.handleQueryParams(queryParams))
)
.subscribe(
() => this.onParamsOrQueryParamsChange()
);
Ответ 5
Вы можете попробовать это:
setTimeout(() => {
this.route.queryParams
.subscribe((params: Params) => {
console.log('PARAMS',params);
}
});
},0);