Angular Material 2 DataSource filter with nested object

删除回忆录丶 提交于 2019-12-03 12:10:23

问题


I have angular 4 project with material 2, I want to filter the data in MatTable. DataSource filter is working fine when we filter data on field which are not nested.

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'},
]);

Filter is working fine for orderNumber, date but not working properly with type field in orderInfo object.


回答1:


DataSource has filterPredicate() method that needs to override in our application as follows. Add this code in your component after data source initialization.

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



回答2:


Here is a solution that incorporates recursion so you don't have to hard code each nested object or their key/value pairs.

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

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

Thanks to @Sagar Kharche for the filterPredicate override.




回答3:


This is a very generic solution and will work for sure. It does not depends on the structure of json, be it simple or nested, this solution works for all.

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



来源:https://stackoverflow.com/questions/49833315/angular-material-2-datasource-filter-with-nested-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!