代码之家  ›  专栏  ›  技术社区  ›  kal93

MatTable上的多个过滤器

  •  3
  • kal93  · 技术社区  · 6 年前

    我一直在尝试应用多列筛选,即列标题中的文本输入将仅对列的内容进行筛选 filterPredicate 属于 MatTableDataSource 但一旦我覆盖了跨列的默认筛选,它就不再工作了。

    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;
      }
    }
    

    StackBlitz

    1 回复  |  直到 6 年前
        1
  •  14
  •   Randal Cunanan    6 年前

    我想你忘了打电话 toLowerCase() 对于 searchString.name

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


    一种方法是在组件类中创建全局筛选器字段。

    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);
    }
    

    然后尝试在其他字段之前使用全局筛选器进行筛选。

      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;
      }
    

    https://stackblitz.com/edit/angular-hbakxo-5jeaic

        2
  •  0
  •   Code Spy    5 年前

    在角度材质表中,可以使用 过滤器预测 属性,并为其提供 自定义筛选器 方法如下

    来源 Link

    演示 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
            }