首页 > 解决方案 > 我应该选择什么事件(更改、keyup 等)以最佳方式使用输入文本过滤数组中的数据

问题描述

我有一个项目,我想过滤一千多个位置的数组中的数据,但出于性能原因,我认为按键重复操作(当用户逐字母写时)非常无效。最有效的方法是什么?

 <input (keyup)="fn_filterData()" ([ngModel])="filter">

 fn_filterData(){
 this.myArray.filter((item)=>{
  return item.search(filter)!=-1;
 })
}

我不知道是否有可能,以便在您停止在文本字段中输入 2 秒后,搜索完成,以使其更优化或类似的东西。

我通常使用管道,但这是在逐个字母输入时激活的。哪个是最好的方法?

标签: angular

解决方案


RxJS的带有debounceTime ()distinctUntilChanged()switchMap()操作符的 observables 可以用来优化地做到这一点。

这种方法确保不会在每次按键时过滤数据(等待给定时间并对字符进行分组),当立即输入相同的键时再次忽略过滤,并且具有其他优点。

请参阅这篇使用 RxJS 在 Angular 中构建实时搜索的帖子,其中在搜索中实现了这一点。

这是如何完成的概述。

模板:

<input [ngModel]="filterKey" (ngModelChange)="onFilterKeyChange($event)">

零件:

filterKey: string;
inputs$ = new Subject<any>();

onFilterKeyChange(key) {
  this.filterKey = key;
  this.inputs$.next({ 'filterKey': this.filterKey });
}

inputs$.pipe(
  debounceTime(750), // Waits until there is no new data for given time.
  distinctUntilChanged( // Only allows distinct data to pass through.
    (p, q) => p.filterKey === q.filterKey
  ),
  switchMap(input => {
    // Has cancelling effect, ignores previous input when new key is entered.

    let key = input.filterKey.trim();

    // Filter the data.
    let result = this.items.filter(item => 
      item.toLowerCase().includes(key.toLowerCase())
    );

    return of(result);
  })
  .subscribe((result) => {
    this.filteredData = result;
  });

当您有数千条记录时,最好在后端过滤它们。在这种情况下,只需将过滤逻辑替换switchMap()为 API 调用即可。

.switchMap((input) => {
    let key = input.filterKey.trim();        
    return dataService.getFilteredData(key);
})

StackBlitz 上的现场演示:https ://stackblitz.com/edit/angular-filtering-using-rxjs


推荐阅读