rxjs 使用combineLatest 过滤数据流 - 流数据不应该为空

问题描述 投票:0回答:1

我正在使用角度组件中的最新组合来将数据流与过滤器文本输入结合在一起:

export class RecordSearchComponent implements OnDestroy {
  @Input() gridData: Observable<TrainingRecord[]> = of([]);

  private filterSubject = new BehaviorSubject<string>('');
  private readonly debounceTimeMs = 300;

  private filterInput$ = this.filterSubject.pipe(
    debounceTime(this.debounceTimeMs),
    distinctUntilChanged(),
  )

  filteredData$ = combineLatest([this.filterInput$, this.gridData]).pipe(
    tap(([filter, data]) => console.log(filter, data)),
    switchMap(([filter, data]) => {
      if (filter === '' || filter === null) {
        return of(data);
      }
      const filterDescriptor = {
        field: 'nameFull',
        operator: 'contains',
        value: filter,
        ignoreCase: true,
      };
      return of(filterBy(data, filterDescriptor));
    })
  );

  ngOnDestroy(): void {
    this.filterSubject.complete();
  }

  onFilter() {
    this.filterSubject.next(this.inputText);
  }
}

filterSubject 正在工作,我可以在控制台中看到结果。

问题是combineLatest中的“gridData”值始终为空。但如果我在模板中单独订阅 gridData,我可以确认数据正在传入。 (gridData | async) 返回所有记录。

angular rxjs observable
1个回答
0
投票

我认为如果我们使用 @Input 像这样初始化,你可能无法在初始化时获得值,为了安全起见,你可以在

ngOnInit
上初始化。

另请注意:gridData 应该在组件初始化时有一个值,然后它才能工作!

export class RecordSearchComponent implements OnDestroy {
  @Input() gridData: Observable<TrainingRecord[]> = of([]);

  private filterSubject = new BehaviorSubject<string>('');
  private readonly debounceTimeMs = 300;
  filteredData$!: Observable<TrainingRecord[]> = of([]);

  private filterInput$ = this.filterSubject.pipe(
    debounceTime(this.debounceTimeMs),
    distinctUntilChanged(),
  )

  ngOnInit() {
    this.filteredData$ = combineLatest([this.filterInput$, this.gridData]).pipe(
        tap(([filter, data]) => console.log(filter, data)),
        switchMap(([filter, data]) => {
          if (filter === '' || filter === null) {
            return of(data);
          }
          const filterDescriptor = {
            field: 'nameFull',
            operator: 'contains',
            value: filter,
            ignoreCase: true,
          };
          return of(filterBy(data, filterDescriptor));
        })
      );
  }

  ngOnDestroy(): void {
    this.filterSubject.complete();
  }

  onFilter() {
    this.filterSubject.next(this.inputText);
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.