代码之家  ›  专栏  ›  技术社区  ›  Ced

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

  •  0
  • Ced  · 技术社区  · 7 年前

    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 回复  |  直到 7 年前
        1
  •  2
  •   paulpdaniels    7 年前

    实际上,是因为 first 是的。当您第一次运行函数时,它正在创建流并订阅 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);
    }
    
    推荐文章