问题描述
我正在尝试对每个列标题中的下拉值过滤角垫表。我可以过滤任何一个下拉值,但不能使用多个下拉值。是否可能有多个下拉菜单?这是我尝试过的。
HTML
<table mat-table [dataSource]="listData">
<ng-container matColumnDef="Name">
<th mat-header-cell *matHeaderCellDef>Name
<br>
<mat-form-field>
<select matNativeControl (change)="onChangeName($event.target.value)">
<option *ngFor="let name of names" [value]="name">
{{name | titlecase}}
</option>
</select>
</mat-form-field>
</th>
<td mat-cell *matCellDef="let row; let rowIndex = index" >
{{row.name}}
</td>
</ng-container>
<ng-container matColumnDef="location ">
<th mat-header-cell *matHeaderCellDef>Location
<mat-form-field>
<select matNativeControl (change)="onChangeLocation($event.target.value)">
<option *ngFor="let location of locations" [value]="location">
{{track | titlecase}}
</option>
</select>
</mat-form-field>
</th>
<td mat-cell *matCellDef="let row; let rowIndex = index" >
{{row.location}}
</td>
</ng-container>
</table>
TS文件
ngOnInit(): void {
this.listData=new MatTableDataSource(res);
}
onChangeName(name){
this.selectedname=name;
if(this.selectedLocation){
this.listData.filter=name+this.selectedLocation;
}
else{
this.listData.filter=name;
}
}
onChangeLocation(location){
this.selectedLocation=location;
if(this.selectedname){
this.listData.filter=location+this.selectedname;
}
else{
this.listData.filter=location;
}
解决方法
这有点棘手,但希望我能帮助您走上正确的轨道。 默认过滤器谓词的工作方式(简化)是它检查所传递的数据对象(即row)的任何属性是否包含所传递的过滤器。
这对您不起作用,因此您将覆盖数据源的filterPredicate。但是,这仍然不能完全解决您的问题-过滤器仅接受字符串对象,并且最好您要传递自定义的“过滤器对象”。要解决它,您可以编写您的DataSource的自定义实现,或在将其作为过滤器传递之前序列化过滤器对象,然后在filterPredicate中反序列化它。
一个简单的实现是(根据您的示例):
private filter: any = {};
ngOnInit(): void {
this.listData = new MatTableDataSource(res);
this.listData.filterPredicate = (data,filter): boolean => {
const filterObject = JSON.parse(filter);
for (const filterProperty in filterObject) {
if (!Object.prototype.hasOwnProperty.call(filterObject,filterProperty)) {
continue;
}
const searchTerm: string = filterObject[filterProperty] ? filterObject[filterProperty].trim().toLowerCase() : '';
const rowValue: string = data[filterProperty] ? data[filterProperty].trim().toLowerCase() : '';
return rowValue.indexOf(searchTerm) > -1;
}
return true;
};
}
onChangeName(name) {
this.updateDataSourceFilter('name',name);
}
onChangeLocation(location) {
this.updateDataSourceFilter('location',location);
}
private updateDataSourceFilter(propertyName: string,value: any): void {
this.filter[propertyName] = value;
this.listData.filter = JSON.stringify(this.filter);
}
这是从我的脑海中冒出来的,因此它可能无法编译-但应向您提供如何自行实现此功能的基本思路。