Angular 8/9 -(动态订阅):如何在从集合中获取 Observable 时自动进行 forkJoin?
Angular 8/9 - (Subscribing dynamically): How to automatically forkJoin while getting Observables from a collection?
第一步:
想象一下,在项目中某处有一个名为 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
)。
我的问题:
什么是最有效的方法,在对象(或集合)中按序列(我感兴趣的)声明 Observable,以便我动态地执行一些操作?
如果没有经过验证的(最先进的)方法,我如何从第一步进入第二步?
能不能省去第二步,更优雅地进入第三步?
编辑 1:
顺便说一句:forkJoin
不适用于路由 (ActivatedRoute) observables,因为路由 observables 没有完成。以下方法有效,但我的问题仍然存在:
// 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;
}
);
}
我为什么要问?
我最大的问题是 "single responsibility",我试图避免复制+粘贴代码(例如上面每个组件中的 routeObservables
,它需要路由相关数据)。
所以主要问题是您有字符串值并且需要将它们用作 Javascript 对象,对吗?在这种情况下,您可以使用方括号访问这些属性:
const keys = Object.keys(this.RouteObservables);
const sources = this.keys.map(key => this[this.RouteObservables.key]);
forkJoin(...this.sources).subscribe(
(routeData: any) => {
this.routeData = routeData;
}
);
p.s。 class 必须在其构造函数中注入 this.route
。
尚未测试,但我认为这应该可以解决问题。如果有任何错误,请告诉我。
第一步:
想象一下,在项目中某处有一个名为 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
)。
我的问题:
什么是最有效的方法,在对象(或集合)中按序列(我感兴趣的)声明 Observable,以便我动态地执行一些操作?
如果没有经过验证的(最先进的)方法,我如何从第一步进入第二步?
能不能省去第二步,更优雅地进入第三步?
编辑 1:
顺便说一句:forkJoin
不适用于路由 (ActivatedRoute) observables,因为路由 observables 没有完成。以下方法有效,但我的问题仍然存在:
// 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;
}
);
}
我为什么要问?
我最大的问题是 "single responsibility",我试图避免复制+粘贴代码(例如上面每个组件中的 routeObservables
,它需要路由相关数据)。
所以主要问题是您有字符串值并且需要将它们用作 Javascript 对象,对吗?在这种情况下,您可以使用方括号访问这些属性:
const keys = Object.keys(this.RouteObservables);
const sources = this.keys.map(key => this[this.RouteObservables.key]);
forkJoin(...this.sources).subscribe(
(routeData: any) => {
this.routeData = routeData;
}
);
p.s。 class 必须在其构造函数中注入 this.route
。
尚未测试,但我认为这应该可以解决问题。如果有任何错误,请告诉我。