【问题标题】:Use multiple filters Angular Material table使用多个过滤器 Angular Material 表
【发布时间】:2021-07-19 17:57:54
【问题描述】:

我有一个 Angular Material 表。我创建了一个与数据源的“过滤器”功能一起使用的搜索栏。我创建了一个 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';
  }

【问题讨论】:

    标签: angular angular-material filtering


    【解决方案1】:

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

    因此,您需要在任一字段中进行更改,更新您的“过滤器对象”,对其进行序列化并使用新值更新 dataSource.filter。这将导致 dataSource 更新其 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);
    }
    

    【讨论】:

      【解决方案2】:
       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'; 
      

      }

      【讨论】:

        猜你喜欢
        • 2019-06-19
        • 2018-03-23
        • 2019-09-19
        • 2016-09-23
        • 2019-05-04
        • 1970-01-01
        • 2017-05-07
        • 2021-07-31
        • 2019-09-04
        相关资源
        最近更新 更多