【问题标题】:How do I filter MatTableDataSource using wildcards如何使用通配符过滤 MatTableDataSource
【发布时间】:2021-09-03 07:03:03
【问题描述】:

我正在使用来自 Angular Material 网站 https://material.angular.io/components/table/examples 的示例 Table with filtering

我想让用户使用通配符进行搜索。在这种情况下,%

我写了以下内容:

    const filterValue = (event.target as HTMLInputElement).value;

    let filterArray = filterValue.trim().toLowerCase().split("%");

    for (let fil of filterArray) {
      //I know this line below won't work, as it will just replace the filter with each iteration, but showing for sake of example
      this.tableData.filter = fil;
      
    }

因此,如果用户在输入字段中键入one%two,我希望过滤器找到在行中某处同时存在单词“one”和“two”的表行。

我尝试了几种代码变体,但似乎没有什么能完全正确。关于如何完成这项工作的任何想法?

【问题讨论】:

    标签: angular typescript angular-material


    【解决方案1】:

    我可以通过在我的 applyFilter() 方法中使用以下代码来完成此操作:

      applyFilter(event: Event) {
        const filterValue = (event.target as HTMLInputElement).value;
    
        let filterArray = filterValue.trim().toLowerCase().split("%");
    
        let filteredData = [];
    
        //loop through each word provided in the filter and push matching arrays from the dataset to filterdData temporary holder
        for (let str of filterArray) {
          filteredData.push(
            this.data.filter((o) =>
              Object.keys(o).some((k) => String(o[k]).toLowerCase().includes(str))
            )
          );
        }
    
        //filter down final dataset with array items that occur in each array producded by each search term provided
        filteredData = filteredData.reduce((a, b) =>
          a.filter((c) => b.includes(c))
        );
    
        this.tableData.data = filteredData;
      }
    

    我能够从每个问题中提取信息以形成适合我需求的解决方案:

    【讨论】:

      【解决方案2】:

      您必须像这样覆盖this.dataSource.filterPredicate 的默认实现:

      constructor() {
          this.dataSource.filterPredicate = ((data, filters) => {
            let match = false;
            const filtersList = JSON.parse(filters);
      
            filtersList.forEach(filterObj => {
              match =
                match || !filterObj ||
                Object.values(data)
                  .map(t => t.toLocaleString().toLocaleLowerCase())
                  .includes(filterObj);
            });
            return match;
          }) as (PeriodicElement, string) => boolean;
        } 
      

      在您的applyFilter 方法中,您需要通过JSON.stringify(filterArray); 将数组传递给filterPredicate,如下所示:

      applyFilter(filterValue: KeyboardEvent) {
          let filterArray = (filterValue.target as any).value
            .trim()
            .toLowerCase()
            .split('%');
          this.dataSource.filter = JSON.stringify(filterArray);
        } 
      

      Here 是我为您编写的完整工作示例。

      【讨论】:

      • stackblitz 示例看起来很棒。但是,在我的应用程序中,一旦通过 ngOnChanges 接收数据,我就会创建表。我当时尝试设置过滤谓词,但一直收到错误Cannot read property 'toLocaleString' of null 我还尝试设置一个空的 matTableDataSource 并像示例一样在构造函数中设置过滤谓词,它不会抛出错误,但没有数据在搜索中输入任何内容后都会返回。
      • 请将您的代码放入 stackblitz 中进行调试。
      • @ts1993 似乎data 为空。在filterPredicate 方法中console.log(data)就好了
      猜你喜欢
      • 1970-01-01
      • 2017-09-09
      • 1970-01-01
      • 2015-04-16
      • 2023-03-09
      • 1970-01-01
      • 2015-08-28
      • 2021-11-12
      • 1970-01-01
      相关资源
      最近更新 更多