В дополнение к предыдущему результату наблюдаемый конвейер работает только один раз - PullRequest
0 голосов
/ 23 июня 2018

живой пример

У меня есть массив фильтров как 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 голосов
/ 23 июня 2018

На самом деле, это из-за first.Когда вы запускаете функцию в первый раз, она создает поток и подписывается на BehaviorSubject.Получив первое событие, он перенаправляет его на BehaviorSubject, а затем завершает BehaviorSubject.Второй раз, когда вы запускаете его, BehaviorSubject уже выключен, поэтому он немедленно отписывается от любых новых подписок на него.

Не зная слишком много о вашей реальной цели, я предлагаю вместо того, чтобы ставить 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);
}
...