typescript MatTable 上的多个过滤器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/52007176/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:36:32  来源:igfitidea点击:

Multiple Filters on MatTable

angulartypescriptangular-material

提问by kal93

I've been trying to apply multi column filtering i.e a text input in column headers will filter only on the contents of the column.So far I've been able to make it work by overriding filterPredicateof MatTableDataSourcebut once I override the default filtering which is across columns no longer works.

我一直在尝试应用多列过滤,即列标题中的文本输入将仅过滤列的内容。到目前为止,我已经能够通过覆盖来使其工作filterPredicateMatTableDataSource但是一旦我覆盖了默认过滤跨列不再有效。

export class TableFilteringExample implements OnInit
{
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
  dataSource = new MatTableDataSource(ELEMENT_DATA);

  positionFilter = new FormControl();
  nameFilter = new FormControl();

  filteredValues =
  {
    position: '',
    name: '',
    weight: '',
    symbol: ''
  };

  ngOnInit()
  {
    this.positionFilter.valueChanges.subscribe((positionFilterValue) =>
    {
      this.filteredValues['position'] = positionFilterValue;
      this.dataSource.filter = JSON.stringify(this.filteredValues);
    });

    this.nameFilter.valueChanges.subscribe((nameFilterValue) =>
    {
      this.filteredValues['name'] = nameFilterValue;
      this.dataSource.filter = JSON.stringify(this.filteredValues);
    });

    this.dataSource.filterPredicate = this.customFilterPredicate();
  }

  applyFilter(filterValue: string)
  {
    this.dataSource.filter = filterValue.trim().toLowerCase();
    this.dataSource.filter = filterValue;
  }

  customFilterPredicate()
  {
    const myFilterPredicate = function(data: PeriodicElement, filter: string): boolean
    {
      let searchString = JSON.parse(filter);

      return data.position.toString().trim().indexOf(searchString.position) !== -1 && data.name.toString().trim().toLowerCase().indexOf(searchString.name)!== -1;
    }

    return myFilterPredicate;
  }
}

What I'm looking for is once column filter is applied the default filter should update the existing filter criteria and return the further filtered data.

我正在寻找的是一旦应用了列过滤器,默认过滤器应该更新现有的过滤条件并返回进一步过滤的数据。

StackBlitz

闪电战

回答by Randal Cunanan

I think you just forgot to call toLowerCase()for searchString.name

我想,你只是忘了打电话toLowerCase()searchString.name

data.name.toString().trim().toLowerCase().indexOf(searchString.name.toLowerCase())!== -1;

data.name.toString().trim().toLowerCase().indexOf(searchString.name.toLowerCase())!== -1;



EDIT: One approach is to create a global filter field in your Component class.

编辑:一种方法是在您的 Component 类中创建一个全局过滤器字段。

globalFilter = '';


<mat-form-field>
  <input matInput [ngModel]="globalFilter" (ngModelChange)="applyFilter($event)" placeholder="Filter">
</mat-form-field>


applyFilter(filter) {
    this.globalFilter = filter;
    this.dataSource.filter = JSON.stringify(this.filteredValues);
}


Then try to filter using global filter first before the other fields.

然后尝试在其他字段之前首先使用全局过滤器进行过滤。

  customFilterPredicate() {
    const myFilterPredicate = (data: PeriodicElement, filter: string): boolean => {
      var globalMatch = !this.globalFilter;

      if (this.globalFilter) {
        // search all text fields
        globalMatch = data.name.toString().trim().toLowerCase().indexOf(this.globalFilter.toLowerCase()) !== -1;
      }

      if (!globalMatch) {
        return;
      }

      let searchString = JSON.parse(filter);
      return data.position.toString().trim().indexOf(searchString.position) !== -1 &&
        data.name.toString().trim().toLowerCase().indexOf(searchString.name.toLowerCase()) !== -1;
    }
    return myFilterPredicate;
  }

Here's the working app: https://stackblitz.com/edit/angular-hbakxo-5jeaic

这是工作应用程序:https: //stackblitz.com/edit/angular-hbakxo-5jeaic

回答by Code Spy

In Angular Material Tables, you can add multi colum filter using filterPredicateproperty on mat-tables and providing them a customFiltermethod as shown below

在 Angular Material Tables 中,您可以使用mat-tables 上的filterPredicate属性添加多列过滤器,并为它们提供customFilter方法,如下所示

Source Link

来源链接

Demo Link

演示链接

enter image description here

在此处输入图片说明

        ngOnInit() {

        // Overrride default filter behaviour of Material Datatable
        this.dataSource.filterPredicate = this.createFilter();
        }

        ...
        ...

        // Custom filter method fot Angular Material Datatable
        createFilter() {
        let filterFunction = function (data: any, filter: string): boolean {
          let searchTerms = JSON.parse(filter);
          let isFilterSet = false;
          for (const col in searchTerms) {
            if (searchTerms[col].toString() !== '') {
              isFilterSet = true;
            } else {
              delete searchTerms[col];
            }
          }

          let nameSearch = () => {
            let found = false;
            if (isFilterSet) {
              for (const col in searchTerms) {
                searchTerms[col].trim().toLowerCase().split(' ').forEach(word => {
                  if (data[col].toString().toLowerCase().indexOf(word) != -1 && isFilterSet) {
                    found = true
                  }
                });
              }
              return found
            } else {
              return true;
            }
          }
          return nameSearch()
        }
        return filterFunction
        }