ng-select 在绑定到 Array.filter() 时变得无响应



ng-select组件绑定到Array.filter()的结果时,从下拉列表中选择一个选项会导致页面无响应。

是否有正确的方法绑定到筛选的项目数组?

堆栈闪电战示例

import { Component } from '@angular/core';
interface IListItem {
  id: number;
  name: string;
}
@Component({
  selector: 'my-app',
  template: `
<ng-select
  [items]="items"
  bindLabel="name"
  placeholder="Select item..."
  [(ngModel)]="selectedItem">
</ng-select>`
})
export class AppComponent  {
  private readonly _items: IListItem[] = [
    { id: 1, name: "One" },
    { id: 2, name: "Two" },
    { id: 3, name: "Three" },
    { id: 4, name: "Four" },
    { id: 5, name: "Five" },
    { id: 6, name: "Six" },
    { id: 7, name: "Seven" },
    { id: 8, name: "Eight" },
    { id: 9, name: "Nine" },
    { id: 10, name: "Ten" }
  ];
  get items(): IListItem[] {
    return this._items.filter(i => i.id % 2 === 0);
  }
  selectedItem: IListItem;
}

不要将函数与 ng-select 一起使用,每次都会调用它,这会使您的 UI 无响应。而是将过滤后的结果分配给变量,

filteredItems  =   this._items.filter(i => i.id % 2 === 0);

STACKBLITZ DEMO

尝试这样的事情,将管道附加到ng选择的项目,如果过滤列表相同,它将返回对过滤列表的引用,以便 NG Select 不会继续运行更改检测,每次都返回一个新列表

externalLookupListFilter = (item) =>tem.id % 2 ===0
<ng-select #dropdown
[items]="lookupList | externalFilter: externalLookupListFilter"
</ng-select>
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'externalFilter'})
export class ExternalFilterPipe implements PipeTransform {
    
    
    private filteredList: Array<any> = undefined;
    transform(list: Array<any>, filterFunction: (item) => boolean, idProperty: string = 'id') {
        
        if (!filterFunction || !list) {
            return list;
        }
        
        const newList = list.filter(filterFunction);
        if(!this.arrayEquals(newList, this.filteredList, idProperty)) {
            this.filteredList = newList;
        }
        
        return this.filteredList;
    }
    
    private arrayEquals(a, b, idProperty) {
        return Array.isArray(a) &&
            Array.isArray(b) &&
            a.length === b.length &&
            (!idProperty ?
                a.every((val, index) => val === b[index]) // if no idproperty compare array as primitive values
                : a.every((val, index) => val[idProperty] === b[index][idProperty])); // if idproperty compare the idProperty of each object in arrays
    }
}

最新更新