如何在不使用filterPredicate的情况下按角度过滤MatTable

时间:2019-07-09 06:37:59

标签: angular typescript mat-table

我有MatTable我想使用values从用户input存储的数据,我可以检查该值是否与数据匹配,但是我不知道如何在不使用filterPredicare的情况下过滤表,因为使用另一个将导致我出现重复问题。

这是我的组件NgOnInit

 ngOnInit() {
    this.marinService.getAllContainers().subscribe((result) => {
     //Data
      this.dataSource = new MatTableDataSource(result);
      //Paginator
      this.dataSource.paginator = this.paginator;
      //AutoFilter Form 1st page
      this.clientType = this.route.snapshot.queryParamMap.get('clientType');
      this.storageType= this.route.snapshot.queryParamMap.get('storageTypes');
      console.log('The Client name is : '+this.clientType+'  '+'The storage Facility is : '+this.storageType);
      this.tableFilter();
      //snapShot Filter
      //CheckBoxFilter
      this.dataSource.filterPredicate = (data: Container, filter: any) => {
        return filter.split(',').every((item: any) => data.SOG_MCOLH.indexOf(item)!== -1);
      };
      this.filterCheckboxes.subscribe((newFilterValue: any[]) => {
        this.dataSource.filter = newFilterValue.join(',');
      });
      });
  }

这是我的function

  tableFilter(){
    var data : Container = this.dataSource;
    var newData: any[];
    if(data.LQOCH_SHM_LOEZI_QTSR = this.clientType){
      console.log(data.LQOCH_SHM_LOEZI_QTSR);
    }else{
      console.log("Hi Not working")
      return this.dataSource;
    }
  }

我尝试使用与filterPrediacte中使用的“过滤方法”相同的方法,但没有成功。

1 个答案:

答案 0 :(得分:1)

我认为,最好修改filterPredicate()以适合您的需求。 mat-table已经过优化,可以提高性能,因此在不使用filterPredicate()的情况下为表创建自己的过滤器可能会导致性能问题。我在stackblitz上有一个有效的示例。

在我的示例中,我正在创建一个过滤器作为以下格式的对象

{
  columnName: Array(filterValues),
  ...
}

(由于在复选框中,您可以基于特定值对特定列进行过滤,并且同一列上可以有多个过滤器)

我正在使用函数updateFilter()来基于所选复选框修改过滤器。如果选中此复选框,则只会将过滤器添加到过滤器对象中,如果未选中,则将其从过滤器对象中删除。然后,此过滤器对象将作为字符串传递给mat-table过滤器(因为filterPredicate()仅接受字符串值)

updateFilter(column: string, filter: string) {
  if (!this.filterValues.hasOwnProperty(column)) {
    this.filterValues[column] = [filter];
  } else {
    this.filterValues[column].includes(filter) ?
    this.filterValues[column] = this.filterValues[column].filter(filterValue => filterValue !== filter) :
    this.filterValues[column].push(filter);
  }

  this.applyFilter();
}

filterPredicate()中,解析过滤器对象并基于该对象过滤数据。我正在使用变量conditions,因为一次可以选择多个复选框(我们将需要传递满足所有选定条件的所有数据。请尝试选择示例中的所有复选框)。对于任何自定义过滤器(例如,显示进度大于90%的所有数据),您可以添加条件。我添加了一个用于名称的自定义过滤器,因为该列同时包含名字和姓氏,而我仅根据名字(名称的子集)进行过滤。

this.dataSource.filterPredicate = ((data: UserData, filter: string): boolean => {
  const filterValues = JSON.parse(filter);
  let conditions = true;

  for (let filterKey in filterValues) {
    if (filterKey === 'name') {
      conditions = conditions && data[filterKey].trim().toLowerCase().indexOf(filterValues[filterKey]) !== -1;
    }
    else if (filterValues[filterKey].length) {
      conditions = conditions && filterValues[filterKey].includes(data[filterKey].trim().toLowerCase());
    }
  }

  return conditions;
});

最后,为了触发过滤器。选中此复选框后,只需调用updateFilter()以及columnName即可过滤通过并输入值。例如。要显示红色,请调用updateFilter('color', 'red'),其中'color'是列名,'red'是过滤器值。

编辑:您可以通过多种方式来完成评论中提到的内容。您可以将值设置为复选框,然后添加template reference variable#color下面是您的模板参考变量。这使您可以使用color.value

在html中访问此复选框值
<mat-checkbox value="blue" (change)="updateFilter('color', color.value)" #color>Show blue colors</mat-checkbox>

如果您在组件中定义了值,并且正在使用[value]将其传递到复选框。您可以再次使用模板引用变量来传递数据,也可以只传递值本身。

组件

name: string = 'Amelia';

HTML

// No interpolation required when passing the value to the function.
<mat-checkbox [value]="name" (change)="updateFilter('name', name)">Show all first name - Amelia</mat-checkbox>

请查看更新后的stackblitz,以了解其实际效果。