Angular Material mat-table 在过滤器时不返回任何结果

Att*_*s29 1 angular-material angular angular-material-table

我尝试使用 Angular Material 包重新创建一个 mat-table。mat-table 示例最近得到了大量改进,这是惊人的。他们在此提供了带有排序和过滤功能的示例

我试图在我自己的应用程序的上下文中重现这一点,在此处的stackblitz 上的最小示例中使用虚拟数据。

该表显示并填充了数据,但是只要我输入一个以上的字母,过滤器方法似乎就会错误地删除所有条目,甚至不应该删除的条目。

我在这里能想到的一个区别是,在我的示例中,我在 dataSource: 的声明中使用了一个类dataSource: MatTableDataSource<Match>;,而在 Angular 人员提供的示例中,它是一个接口:dataSource: MatTableDataSource<UserData>;

然而,这也很可能是一个红鲱鱼,因为我尝试使用界面而不是成功。非常感谢这里的任何帮助。

ter*_*rtz 8

在官方的 Angular stackblitz 示例中,dataSource有一个深度为 1 级的对象数组,通过执行以下操作可以明显看出console.log(this.dataSource.filteredData)

在此处输入图片说明

dataSource但是,您在 Match 对象中嵌套了另一层对象,两次(即 MatchDetails 和 MoveInVideo 对象嵌套在 Match 对象内):

在此处输入图片说明

因此,提供的过滤器函数对您不起作用,因为它只根据过滤器值检查对象的第一级(匹配)。事实上,它通过返回正常工作,[]因为您的 Match 对象中的任何值都与过滤器值不匹配。如果您搜索“originalFilterPosterId”,它将返回所有对象,因为所有匹配对象都包含此值。

您可以通过filterPredicate在调用applyFilter()事件处理程序之前在 ngOnInit() 中设置泛型来解决此问题。这个通用函数将能够过滤嵌套对象。@Sagar Kharche 和 @mighty_mite Stackover 答案来源的所有功劳。

ngOnInit(){
  this.dataSource.paginator = this.paginator;
  this.dataSource.sort = this.sort;

  //set a new filterPredicate function
  this.dataSource.filterPredicate = (data, filter: string) => {
    const accumulator = (currentTerm, key) => {
      return this.nestedFilterCheck(currentTerm, data, key);
    };
    const dataStr = Object.keys(data).reduce(accumulator, '').toLowerCase();
    // Transform the filter by converting it to lowercase and removing whitespace.
    const transformedFilter = filter.trim().toLowerCase();
    return dataStr.indexOf(transformedFilter) !== -1;
  }
}

//also add this nestedFilterCheck class function
nestedFilterCheck(search, data, key) {
  if (typeof data[key] === 'object') {
    for (const k in data[key]) {
      if (data[key][k] !== null) {
        search = this.nestedFilterCheck(search, data[key], k);
      }
    }
  } else {
    search += data[key];
  }
  return search;
}

Run Code Online (Sandbox Code Playgroud)

您无需更改applyFilter()函数中的任何内容。

分叉 Stackblitz 示例?