输入数组过滤后,角度异步管道不刷新结果

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

在父组件中,我有一个Tour [] tours_filtered: Observable<Tour[]>流,我在http请求的subscribe函数中分配

this.api.getTours().subscribe(
  result => {
    this.tours_filtered = of(result.tours);
  }
)

在视图中,我使用异步管道显示流

<app-tour-box [tour]="tour" *ngFor="let tour of tours_filtered | async"></app-tour-box>

到目前为止所有工作都按预期进行。在子组件中,我有一个输入文本,它发出用户插入的值,以过滤Tour by title的数组。

在父组件中我监听函数中发出的值,我切换到使用switchMap过滤了该值的Tour []的新流

onSearchTitle(term: string) {
  this.tours_filtered.pipe(
    switchMap( 
      (tours) => of( tours.filter((tour) => tour.name.toLowerCase().includes(term)) )
    )
  )
}

我认为异步管道一直在监听以反映应用它的数组的变化,所以我认为我不必在上面的函数中订阅,但是当我输入输入时,视图中没有任何变化过滤结果。

如果我将新流分配给subscribe函数中的原始数组,则结果会正确更新


    onSearchTitle(term: string) {
        this.tours_filtered.pipe(
          switchMap((tours) => of(tours.filter((tour) => tour.name.toLowerCase().includes(term))))
        ).subscribe( val => { this.tours_filtered = of(val); })
      }

这个程序是否正确?我可以避免订阅因为我已经使用了异步管道吗?有更好的方法来实现我的目标吗?

编辑:

也许我找到了一个解决方案,我必须像这样为变量分配一个新流

onSearchTitle(term: string) {
    this.tours_filtered = of(this.city.tours).pipe(
      switchMap((tours) => of(tours.filter((tour) => tour.name.toLowerCase().includes(term))))
    );
  }

我不需要再次订阅,视图中的结果会根据用户键入的搜索词进行更改。这是正确的方法吗?

javascript angular observable
1个回答
0
投票

我认为在您的情况下,解决方案应该如下工作:

onSearchTitle(term: string) {
  this._searchTerm = term;
  this.tours_filtered = of( 
    this.city.tours.filter((tour) => tour.name.toLowerCase().includes(term))
  )
}

因为在您的示例中,您不会更改ngFor中使用的observable。因此它不起作用。

但是,我没有看到在这里使用observable的原因,除非这是第一步,你将来要从服务器获取这些数据


UPDATE

对您而言,最佳解决方案是将您的输入视为可观察的并观察更改:

// your.component.ts
export class AppComponent  {

  searchTerm$ = new BehaviorSubject<string>('');
  results = this.search(this.searchTerm$);

  search(terms: Observable<string>) {
    return terms
      .pipe(
        debounceTime(400),
        distinctUntilChanged(),
        switchMap(term => {
          return of(this.city.tours.filter((tour) => tour.name.toLowerCase().includes(term)))
        }
        )
      )
  }

}
// your.template.html
...
<input type="" (input)="searchTerm$.next($event.target.value)">
...

此外,添加debounceTimedistinctUntilChanged以获得更好的用户体验和更少的搜索请求将会很棒。

有关详细信息,请参阅full example。另外,请参阅this article以获得更详细的解释

© www.soinside.com 2019 - 2024. All rights reserved.