我有以下问题。我想使用Angular中的异步管道订阅一个可观察的对象。但是管道中的数据可以源自不同的数据源,并且管道可以根据数据源看起来有所不同。
现在它的实现方式不起作用,因为我覆盖了this.data$
的第一个值,因此源A从未得到订阅。
是否可以根据过滤器“拆分”管道?
problem.component.ts:
// Data source A and logic A
this.data$ = this.service.context.pipe(
filter(context => context.flag === true),
switchMap(context => this.dataSourceA(context.id))
map(data => this.processDataA(data))
);
// Data source B and logic B
this.data$ = this.service.context.pipe(
filter(context => context.flag === false),
switchMap(context => this.dataSourceB(context.id))
map(data => this.processDataB(data))
);
problem.component.html
<pro-table [data]="data$ | async"></pro-table>
答案 0 :(得分:4)
将逻辑移至您的switchMap()
this.data$ = this.service.context.pipe(
switchMap(context => context.flag
? this.dataSourceA(context.id).pipe(map(d => this.processDataA(d)))
: this.dataSourceB(context.id).pipe(map(d => this.processDataB(d)))
)
);
答案 1 :(得分:0)
这是获得所需结果的错误方法。您必须接管一个称为“高阶可观察”的事物:Observable<Observable<T>>
。就像“高阶函数”(能够基于其参数生成另一个函数)一样,此人能够根据您依赖的任何参数化来生成另一个Observable
。
this.service.context.pipe(
switchMap(context => context.flag ? this.dataSourceA(context.id).pipe(...) : this.dataSourceB(context.id).pipe(...))
);
...一开始似乎有点深奥,但实际上不是。 \
P.S。要记住的要点:高阶可观察值让您以一种奇特的方式对流进行参数化:通过处理流。
答案 2 :(得分:0)
您可以添加一个Subject
,它将捕获许多数据源并进行订阅:
this.data$ = new Subject();
observer = {
next(data) { this.data$.next(data) },
error(msg) { /*handle error*/ }
};
// Data source A and logic A
this.service.context.pipe(
filter(context => context.flag === true),
switchMap(context => this.dataSourceA(context.id))
map(data => this.processDataA(data))
).subscribe(observer);
this.service.context.pipe(
filter(context => context.flag === false),
switchMap(context => this.dataSourceB(context.id))
map(data => this.processDataB(data))
).subscribe(observer);
在这种情况下,您似乎可以使用该标志将其保留在一个块中:
this.service.context.pipe(
switchMap(context => context.flag ?
this.dataSourceA(context.id) : this.dataSourceB(context.id)
)
map(data => this.processData(data)) // handle both cases
).subscribe(observer);