Первый шаг:
Представьте, что где-то в проекте есть объект с именем RouteObservables
, который я хочу использовать (импортировать) во многих компонентах:
export const RouteObservables = {
state$: 'this.route.paramMap.pipe(map(() => window.history.state))',
url$: 'this.route.url',
params$: 'this.route.params',
queryParams$: 'this.route.queryParams',
fragment$: 'this.route.fragment',
data$: ' this.route.data'
};
Второй шаг:
Я хочу перейти к следующей ситуации (с помощью объекта RouteObservables выше):
const state$ = this.route.paramMap.pipe(map(() => window.history.state));
const url$ = this.route.url;
const params$ = this.route.params;
const queryParams$ = this.route.queryParams;
const fragment$ = this.route.fragment;
const data$ = this.route.data;
Третий шаг
Я хочу использовать ту же коллекцию RouteObservables
для автоматического запуска forkJoin
:
forkJoin([...Object.keys(RouteObservables)]).subscribe(
(routeData: any) => {
this.routeData = routeData;
}
);
Зачем мне нужен объект RouteObservables
?
Мне нужна упорядоченная последовательность для доступа к правильным данным (например, routeData[0]
будет моим объектом состояния, потенциально переданным с предыдущего маршрута). Этот объект помогает мне не пропустить некоторые подписки, чтобы отписаться в конце (ngOnDestroy
) тоже.
Мой вопрос (ы):
Каков наиболее эффективный способ объявить Observables в последовательности (меня интересует) в объекте (или в коллекции), чтобы я мог выполнять некоторые операции динамически?
Если не существует проверенного (современного) способа, как я могу перейти от первого шага ко второму шагу?
Можно ли вообще сэкономить второй шаг и более элегантно перейти к третьему шагу?
Edit1:
Кстати: forkJoin
не работает с наблюдаемыми маршрутами (ActivatedRoute) таким образом, потому что наблюдаемые маршрута не завершены. Следующий подход работает, но мои вопросы все еще существуют:
// excerpt!
// routeData is a public property
ngOnInit() {
this.getAllRouteData();
}
getAllRouteData() {
const state$ = this.route.paramMap.pipe(map(() => window.history.state));
const url$ = this.route.url;
const params$ = this.route.params;
const queryParams$ = this.route.queryParams;
const fragment$ = this.route.fragment;
const data$ = this.route.data;
forkJoin(
state$.pipe(first()),
url$.pipe(first()),
params$.pipe(first()),
queryParams$.pipe(first()),
fragment$.pipe(first()),
data$.pipe(first())
).subscribe(
(routeData: any) => {
this.routeData = routeData;
this.start();
},
(error: any) => {
console.log('Error: ', error);
}
);
}
Edit2: Текущий обходной путь (routeObservables
на самом деле повторно не используется в других компонентах)
getAllRouteData() {
const routeObservables = [
this.route.paramMap.pipe(map(() => window.history.state)),
this.route.url,
this.route.params,
this.route.queryParams,
this.route.fragment,
this.route.data
];
forkJoin(routeObservables.map(r => r.pipe(first()))).subscribe(
(routeData: any) => {
this.routeData = routeData;
}
);
}
Почему я спрашиваю?
Моя самая большая проблема - «единственная ответственность», я стараюсь избегать копирования + вставки кода (например, routeObservables
выше в каждом компоненте, который нуждается в маршруте, связанном с данные).