Угловой материал 2 Фильтр DataSource с вложенным объектом
У меня есть угловой проект 4 с материалом 2, я хочу отфильтровать данные в 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.
Ответы
Ответ 1
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;
};
Ответ 2
Вот решение, которое включает рекурсию, поэтому вам не нужно жестко кодировать каждый вложенный объект или пар их/значение.
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;
}
Спасибо @Sagar Kharche за filterPredicate
.
Ответ 3
Это очень общее решение и будет работать точно. Это не зависит от структуры JSON, будь то простой или вложенный, это решение работает для всех.
this.dataSource.filterPredicate = (data: any, filter) => {
const dataStr =JSON.stringify(data).toLowerCase();
return dataStr.indexOf(filter) != -1;
}