настраиваемый фильтр в мат-таблице
Я использую мат-таблицу. Он имеет фильтр, который отлично работает с документом doc:
Из https://material.angular.io/components/table/overview исходный код:
<div class="example-header">
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
</mat-form-field>
</div>
<mat-table #table [dataSource]="dataSource">
<!-- the rest of the code -->
</mat-table>
export class TableFilteringExample {
displayedColumns = ['position', 'name', 'weight', 'symbol'];
dataSource = new MatTableDataSource(ELEMENT_DATA);
applyFilter(filterValue: string) {
filterValue = filterValue.trim(); // Remove whitespace
filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
this.dataSource.filter = filterValue;
}
}
const ELEMENT_DATA: Element[] = [
{position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H'},
{position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'},
{position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li'},
{position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be'},
{position: 5, name: 'Boron', weight: 10.811, symbol: 'B'}
];
С этой реализацией, когда фильтр фильтруется, для любого столбца.
Теперь я пытаюсь изменить фильтр, потому что я хочу, это фильтр только для столбца "name", поэтому я пытаюсь переписать фильтр и назначить filterData.
applyFilter(filterValue: string) {
filterValue = filterValue.trim(); // Remove whitespace
filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
this.dataSource.filteredData = this.filterByEmail(filterValue);
console.log(this.dataSource.filteredData); //value is what I want.
}
filterByName(filter: string): any {
const dataFiltered = this.data.filter(function(item){
return item.name.indexOf(filter) > -1
})
return dataFiltered;
}
В консоли я вижу, что this.dataSource.filteredData имеет данные, которые я хочу распечатать, но таблица не перезагружается.
Что мне не хватает?
Ответы
Ответ 1
Я нашел решение здесь.
Необходимо переписать filterPredicate
и просто использовать его как обычно, filterPredicate
должен возвращать true
когда фильтр проходит, и false
когда он не
export interface Element {
name: string;
position: number;
weight: number;
symbol: string;
}
dataSource = new MatTableDataSource(ELEMENT_DATA);
/* configure filter */
this.dataSource.filterPredicate =
(data: Element, filter: string) => data.name.indexOf(filter) != -1;
applyFilter(filterValue: string) {
filterValue = filterValue.trim(); // Remove whitespace
filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
this.dataSource.filter = filterValue;
}
Ответ 2
Не забудьте применить .trim().toLowerCase()
к вашим данным или вы можете столкнуться с неожиданными результатами. См. Мой пример ниже:
this.dataSource.filterPredicate = (data:
{name: string}, filterValue: string) =>
data.name.trim().toLowerCase().indexOf(filterValue) !== -1;
applyFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
}
Ответ 3
Помните, что все поля класса, отображаемые в строках таблицы, подлежат фильтрации, даже если вы не отображаете это поле в виде столбца.
export class City {
id: number;//is not displayed in mat table
code: string;
name: string;
country:Country;
}
Любой фильтр для источника данных таблицы города также применяется к столбцу идентификатора, который обычно не отображается для конечного пользователя.
//this filter will also apply to id column
this.cityDataSource.filter = filterValue;