如何在没有 filterPredicate 的情况下过滤 angular 中的 MatTable

How to filter a MatTable in angular without filterPredicate

我有 MatTable,我想使用 values 过滤,我从用户那里存储 input 我能够检查该值是否与数据匹配,但我没有知道如何在不使用 filterPredicare 的情况下过滤 table,因为使用另一个会给我带来重复问题。

这是我的组件 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 中相同的 "filtering method",但没有成功。

在我看来,最好修改 filterPredicate() 以满足您的需要。 mat-table 已经过优化以提高性能,因此在不使用 filterPredicate() 的情况下为 table 创建自己的过滤器可能会导致性能问题。我在 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() 以及要过滤的列名和值。例如。要显示红色,请调用 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 以了解实际效果。

对我有用

this.dataSource.filterPredicate = function (data, filter: string): boolean {      
  return !!data.name? data.name.trim().toLowerCase().includes(filter.toLowerCase()) : null;
};
this.dataSource.filter = event.trim().toLowerCase();