combineLatest запускается только для первого события

#angular #typescript #rxjs #observable #combinelatest

#угловатый #машинописный текст #rxjs #наблюдаемый #комбинировать последние

Вопрос:

У меня есть 3 события, которые я хочу объединить, и когда одно из них будет запущено, вызвать службу. Я использовал combineLatest , но это работает только в том случае , если первое событие запускается filterChanged .

filterChanged это локальное событие, в то время как остальные события происходят из дочернего компонента. Как я могу это исправить, чтобы выдать одно из событий, даже при инициализации страницы?

 filterChanged = new EventEmitter<boolean>();
paginatorChanged = new EventEmitter<MatPaginator>();
sortChanged = new EventEmitter<{}>();

ngAfterViewInit(): void {
   combineLatest(
      this.paginatorChanged,
      this.sortChanged,
      this.filterChanged
   ).pipe(
      startWith([null, null, null]),
      switchMap(value => {
      const paginator = value[0];
      const sort = value[1];
      const filters = value[2];
    
      return this.service.getFiltered(paginator, sort, filters);
   })).subscribe(data => this.data = data);
}    

applyFilter(): void {
  this.filterChanged.emit(true);
}

onPaginatorChanged(paginator): void {
  this.paginatorChanged.emit(paginator);
}

onSortChanged(sort): void {
  this.sortChanged.emit(sort);
}
 

Спасибо

Ответ №1:

На данный момент вопрос неясен, но если вы хотите запустить combineLatest без filterChanged наблюдаемого излучения хотя бы один раз, то я бы сказал, что вы неправильно используете startWith оператор. Оно должно передаваться по каналу каждому источнику, наблюдаемому индивидуально.

Попробуйте выполнить следующее

 ngAfterViewInit(): void {
  combineLatest(
    this.paginatorChanged.pipe(startWith(null)),
    this.sortChanged.pipe(startWith(null)),
    this.filterChanged.pipe(startWith(null))
  ).pipe(
    switchMap(value => {
    const paginator = value[0];
    const sort = value[1];
    const filters = value[2];
  
    return this.service.getFiltered(paginator, sort, filters);
    })
  ).subscribe(data => this.data = data);
}
 

Также для локальных многоадресных наблюдаемых вы можете использовать RxJS Subject (или его братьев и сестер) вместо использования Angular specific EventEmitter .

Комментарии:

1. Это здорово, спасибо. Я думал, что могу использовать startWith() для всех результатов событий, но было необходимо указать его для каждого. Это рефакторинг, после удаления всех фильтров, сортировки и разбиения на страницы из интеллектуального компонента я изменю События с помощью Subject (внутри сервиса или даже селекторов ngrx (потому что он уже используется в приложении)). Большое спасибо