具有嵌套对象

时间:2018-04-14 15:53:02

标签: angular angular-material2

我有材质2的角度4项目,我想过滤MatTable中的数据。当我们过滤未嵌套的字段上的数据时,DataSource过滤器工作正常。

this.dataSource = new MatTableDataSource([
     { orderNumber: 1, orderInfo: { type: 'ABC'}, date: '12/3/2012 9:42:39 AM'},
     { orderNumber: 3, orderInfo: { type: 'Hello' }, date: '12/2/2018 9:42:39 AM'},
]);

过滤器对orderNumber,日期工作正常,但在orderInfo对象中没有与type字段一起正常工作。

3 个答案:

答案 0 :(得分:13)

DataSource有filterPredicate()方法需要在我们的应用程序中覆盖,如下所示。数据源初始化后,在组件中添加此代码。

this.dataSource.filterPredicate = (data, filter: string)  => {
  const accumulator = (currentTerm, key) => {
    return key === 'orderInfo' ? currentTerm + data.orderInfo.type : 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;
};

答案 1 :(得分:9)

这是一个包含递归的解决方案,因此您不必对每个嵌套对象或其键/值对进行硬编码。

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

nestedFilterCheck

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

感谢filterPredicate替换@Sagar Kharche

答案 2 :(得分:8)

这是一个非常通用的解决方案,可以肯定地起作用。它不依赖于json的结构,无论是简单的还是嵌套的,此解决方案都适用。

this.dataSource.filterPredicate = (data: any, filter) => { const dataStr =JSON.stringify(data).toLowerCase(); return dataStr.indexOf(filter) != -1; }