使用多个过滤器 Angular Material table

Use multiple filters Angular Material table

我有一个 Angular Material table。我创建了一个搜索栏,它与数据源的“过滤器”功能一起使用。我创建了一个 mat select,它与数据源的“filterpredicate”功能一起使用。当我只使用其中一个时,它们都可以工作。但是当我使用一个时,第二个将无法正常工作。不知道如何同时使用两个滤镜

search(event: Event) {
    const filterValue = (event.target as HTMLInputElement).value;
    this.dataSource.data = this.dataSource.filteredData;
}
setTypeOfError(error): void {
    this.dataSource.filterPredicate = (myObject: MyObject, filter: string) => {
      // return true if the myObject should be displayed
      return this.selection.length > 0
        ? this.selection.some(error => error === myObject.error)
        : true;
    };

    this.dataSource.filter = 'only used to trigger filter';
  }

您将需要一个可以同时处理这两个字段的 filterPredicate。请注意,filterPredicate 只接受字符串作为过滤值 - 因此很可能您需要在将过滤值传递给数据源之前对其进行序列化,然后在 filterPredicate.[=16= 中对其进行反序列化。 ]

因此,您需要更改任一字段更新您的“过滤器对象”,将其序列化并使用新值更新 dataSource.filter。这将导致数据源更新其 filteredData.

的值

从我的头顶写下来,所以如果需要,请相应地修改:

// It would be better to have this strongly typed to match all the possible filtering criteria.
filterObject = {
    search: "";
    errorTypes: [];
};

// Set this once after your datasource have been initialized, and don't change it afterwards. It needs to handle all combinantions of different filters that you apply.
this.dataSource.filterPredicate = (row: MyObject, filter: string) => {
      const filterObj = JSON.parse(filter);
      // A sample filter logic - joining both filters with AND.
      return (!filterObj.search || row.name.includes(filterObj.search)) &&
        (filterObject.errorTypes.length === 0 || filterObject.errorTypes.some(e => e === row.error);
};

// This handles the change of your search. Personally I would bind it to FormControl using reactive forms, but I guess that's a matter of preference
search(e: Event): void {
    const filterValue = (event.target as HTMLInputElement).value;
    this.filterObject.search = filterValue;
    this.dataSource.filter = JSON.stringify(this.filterObject);
}

// Handle changes of your select. Not sure about the typing here either since you didn't provide stackblitz.
matSelectChanged(selectedItems: string[]): void {
    this.filterObject.errorTypes = selectedItems;
    this.dataSource.filter = JSON.stringify(this.filterObject);
}
 setTypeOfError(error): void {
this.dataSource.filterPredicate = (myObject: MyObject, filter: string) => {
  const filterValue = (event.target as HTMLInputElement).value;
  // return true if the myObject should be displayed
  // Write logic to find with selection
  let foundInSelection =  this.selection.length > 0
    ? this.selection.some(error => error === myObject.error)
    : true;

  // Write logic to find with search text
  let foundWithSearchKey = filterValue ? false : true;
  for (const key in myObject) {
    if (Object.prototype.hasOwnProperty.call(object, key)) {
      const element: string = object[key];
      if(element) {
        if(element.includes(filterValue)) {
          foundWithSearchKey = true;
          break;
        }
      }
      
    }
  }

  return foundInSelection && foundWithSearchKey;
};

this.dataSource.filter = 'only used to trigger filter'; 

}