添加到以前的结果中,可观察管道仅运行一次

时间:2018-06-23 14:45:19

标签: rxjs rxjs5 rxjs6

live example

我有一个Observable过滤器数组,我想从中添加/删除过滤器。这是我拥有的代码,该代码当前仅在函数首次运行时添加Filter

第二次没有任何反应。

private _filters$ = new BehaviorSubject<Filter[]>([]);

addFilter(added: Filter) {
    debugger
    // adding to array of filters
    this._filters$.pipe(
        tap(d => { debugger; }),
        first(), 
        map(filters => ([...filters, added]))
    ).subscribe(this._filters$);
}

所以我的问题是:为什么会这样?为什么只运行一次? (顺便说一下,first()不是原因)。

我知道我可以使代码像这样工作:

private _filters$ = new BehaviorSubject<Filter[]>([]);

currentFilters;

init() {
   this._filters$.subscribe(f => this.currentFilters = f);
}

addFilter(added: Filter) {
    this._filters$.next([...this.currentFilters, added]);
}

1 个答案:

答案 0 :(得分:2)

实际上是因为first。首次运行该函数时,它将创建流并订阅BehaviorSubject。收到第一个事件后,它将转发给BehaviorSubject,然后完成BehaviorSubjectBehaviorSubject已第二次运行,因此它立即取消订阅任何新的订阅。

在不了解您的实际目标的情况下,我的建议是不要将BehaviorSubject放在管道的底部,而应该将其放在管道的顶部。

// You don't actually need the caching behavior yet so just use a `Subject`
private _filters$ = new Subject<Filter>()

// Hook this up to whatever is going to be using these filters
private _pipeline$ = this._filters.pipe(
  // Use scan instead mapping back into self
  scan((filters, newFilter) => ([...filters, newFilter]), []),
  // Store the latest value for new subscribers
  shareReplay(1)
);

// Now this method is just pushing into the `Subject` and the pipeline never has to be torn down
addFilter(added: Filter) {
    debugger
    this._filters$.next(added);
}