使用多个过滤器 Angular Material table
Use multiple filters Angular Material table
我有一个 Angular Material table。我创建了一个搜索栏,它与数据源的“过滤器”功能一起使用。我创建了一个 mat select,它与数据源的“filterpredicate”功能一起使用。当我只使用其中一个时,它们都可以工作。但是当我使用一个时,第二个将无法正常工作。不知道如何同时使用两个滤镜
search(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
this.dataSource.data = this.dataSource.filteredData;
}
setTypeOfError(error): void {
this.dataSource.filterPredicate = (myObject: MyObject, filter: string) => {
// return true if the myObject should be displayed
return this.selection.length > 0
? this.selection.some(error => error === myObject.error)
: true;
};
this.dataSource.filter = 'only used to trigger filter';
}
您将需要一个可以同时处理这两个字段的 filterPredicate
。请注意,filterPredicate
只接受字符串作为过滤值 - 因此很可能您需要在将过滤值传递给数据源之前对其进行序列化,然后在 filterPredicate
.[=16= 中对其进行反序列化。 ]
因此,您需要更改任一字段更新您的“过滤器对象”,将其序列化并使用新值更新 dataSource.filter
。这将导致数据源更新其 filteredData
.
的值
从我的头顶写下来,所以如果需要,请相应地修改:
// It would be better to have this strongly typed to match all the possible filtering criteria.
filterObject = {
search: "";
errorTypes: [];
};
// Set this once after your datasource have been initialized, and don't change it afterwards. It needs to handle all combinantions of different filters that you apply.
this.dataSource.filterPredicate = (row: MyObject, filter: string) => {
const filterObj = JSON.parse(filter);
// A sample filter logic - joining both filters with AND.
return (!filterObj.search || row.name.includes(filterObj.search)) &&
(filterObject.errorTypes.length === 0 || filterObject.errorTypes.some(e => e === row.error);
};
// This handles the change of your search. Personally I would bind it to FormControl using reactive forms, but I guess that's a matter of preference
search(e: Event): void {
const filterValue = (event.target as HTMLInputElement).value;
this.filterObject.search = filterValue;
this.dataSource.filter = JSON.stringify(this.filterObject);
}
// Handle changes of your select. Not sure about the typing here either since you didn't provide stackblitz.
matSelectChanged(selectedItems: string[]): void {
this.filterObject.errorTypes = selectedItems;
this.dataSource.filter = JSON.stringify(this.filterObject);
}
setTypeOfError(error): void {
this.dataSource.filterPredicate = (myObject: MyObject, filter: string) => {
const filterValue = (event.target as HTMLInputElement).value;
// return true if the myObject should be displayed
// Write logic to find with selection
let foundInSelection = this.selection.length > 0
? this.selection.some(error => error === myObject.error)
: true;
// Write logic to find with search text
let foundWithSearchKey = filterValue ? false : true;
for (const key in myObject) {
if (Object.prototype.hasOwnProperty.call(object, key)) {
const element: string = object[key];
if(element) {
if(element.includes(filterValue)) {
foundWithSearchKey = true;
break;
}
}
}
}
return foundInSelection && foundWithSearchKey;
};
this.dataSource.filter = 'only used to trigger filter';
}
我有一个 Angular Material table。我创建了一个搜索栏,它与数据源的“过滤器”功能一起使用。我创建了一个 mat select,它与数据源的“filterpredicate”功能一起使用。当我只使用其中一个时,它们都可以工作。但是当我使用一个时,第二个将无法正常工作。不知道如何同时使用两个滤镜
search(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
this.dataSource.data = this.dataSource.filteredData;
}
setTypeOfError(error): void {
this.dataSource.filterPredicate = (myObject: MyObject, filter: string) => {
// return true if the myObject should be displayed
return this.selection.length > 0
? this.selection.some(error => error === myObject.error)
: true;
};
this.dataSource.filter = 'only used to trigger filter';
}
您将需要一个可以同时处理这两个字段的 filterPredicate
。请注意,filterPredicate
只接受字符串作为过滤值 - 因此很可能您需要在将过滤值传递给数据源之前对其进行序列化,然后在 filterPredicate
.[=16= 中对其进行反序列化。 ]
因此,您需要更改任一字段更新您的“过滤器对象”,将其序列化并使用新值更新 dataSource.filter
。这将导致数据源更新其 filteredData
.
从我的头顶写下来,所以如果需要,请相应地修改:
// It would be better to have this strongly typed to match all the possible filtering criteria.
filterObject = {
search: "";
errorTypes: [];
};
// Set this once after your datasource have been initialized, and don't change it afterwards. It needs to handle all combinantions of different filters that you apply.
this.dataSource.filterPredicate = (row: MyObject, filter: string) => {
const filterObj = JSON.parse(filter);
// A sample filter logic - joining both filters with AND.
return (!filterObj.search || row.name.includes(filterObj.search)) &&
(filterObject.errorTypes.length === 0 || filterObject.errorTypes.some(e => e === row.error);
};
// This handles the change of your search. Personally I would bind it to FormControl using reactive forms, but I guess that's a matter of preference
search(e: Event): void {
const filterValue = (event.target as HTMLInputElement).value;
this.filterObject.search = filterValue;
this.dataSource.filter = JSON.stringify(this.filterObject);
}
// Handle changes of your select. Not sure about the typing here either since you didn't provide stackblitz.
matSelectChanged(selectedItems: string[]): void {
this.filterObject.errorTypes = selectedItems;
this.dataSource.filter = JSON.stringify(this.filterObject);
}
setTypeOfError(error): void {
this.dataSource.filterPredicate = (myObject: MyObject, filter: string) => {
const filterValue = (event.target as HTMLInputElement).value;
// return true if the myObject should be displayed
// Write logic to find with selection
let foundInSelection = this.selection.length > 0
? this.selection.some(error => error === myObject.error)
: true;
// Write logic to find with search text
let foundWithSearchKey = filterValue ? false : true;
for (const key in myObject) {
if (Object.prototype.hasOwnProperty.call(object, key)) {
const element: string = object[key];
if(element) {
if(element.includes(filterValue)) {
foundWithSearchKey = true;
break;
}
}
}
}
return foundInSelection && foundWithSearchKey;
};
this.dataSource.filter = 'only used to trigger filter';
}