在Angular资料官方网站上提到filterPredicate:((data:T,filter:string)=> boolean)将根据特定字段过滤数据。但是没有得到如何开始。
我见过示例但没有得到: - https://stackblitz.com/edit/angular-material2-table?file=app%2Fapp.component.html
默认情况下,它基于整个对象进行过滤,但我只想基于json的单个属性进行搜索。
答案 0 :(得分:11)
我设法这样做了:
{{1}}
答案 1 :(得分:8)
只需在组件中声明一个带有以下声明的函数,然后将其分配给DataSource.filterPredicate。要使用过滤器,只需为DataSource.filter属性指定一个字符串。
customFilter(Data: T, Filter: string): boolean {
return <true if Data matches filter>
}
答案 2 :(得分:6)
每列上的工作过滤器,演示链接Stackblitz。
要过滤mat-table中的特定列,请为该列添加一个搜索字段,如下所示;
In [32]: %timeit np.frombuffer(x.tobytes(), dtype='S16')
2.8 µs ± 318 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [33]: %timeit np.fromiter((row.tobytes() for row in x), dtype='S16')
614 µs ± 18.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
然后我们将输入从ReactiveFormsModule连接到FormControls。
<mat-form-field class="filter" floatLabel="never">
<mat-label>Search</mat-label>
<input matInput [formControl]="nameFilter">
</mat-form-field>
};
我们将观察过滤器输入的值,并在更改过滤器对象和数据源的过滤器属性时对其进行修改。我们必须将过滤器对象的字符串化版本分配给数据源的过滤器属性
filterValues = {
name: '',
id: '',
colour: '',
pet: ''
}
我们必须更改数据源的filterPredicate才能告诉它如何解释过滤器信息。
ngOnInit() {
this.nameFilter.valueChanges
.subscribe(
name => {
this.filterValues.name = name;
this.dataSource.filter = JSON.stringify(this.filterValues);
}
)
this.idFilter.valueChanges
.subscribe(
id => {
this.filterValues.id = id;
this.dataSource.filter = JSON.stringify(this.filterValues);
}
)
this.colourFilter.valueChanges
.subscribe(
colour => {
this.filterValues.colour = colour;
this.dataSource.filter = JSON.stringify(this.filterValues);
}
)
this.petFilter.valueChanges
.subscribe(
pet => {
this.filterValues.pet = pet;
this.dataSource.filter = JSON.stringify(this.filterValues);
}
)
}
答案 3 :(得分:1)
您可以按照动态列进行过滤,例如没有硬编码的列名,请执行以下操作:
// On input focus: setup filterPredicate to only filter by input column
setupFilter(column: string) {
this.dataSource.filterPredicate = (d: TableDataSourceType, filter: string) => {
const textToSearch = d[column] && d[column].toLowerCase() || '';
return textToSearch.indexOf(filter) !== -1;
};
}
applyFilter(filterValue: string) {
this.dataSource.filter = filterValue.trim().toLowerCase();
}
在模板中,您可以具有以下内容:
<ng-container matColumnDef="item-filter">
<th mat-header-cell *matHeaderCellDef>
<input (keyup)="applyFilter($event.target.value)" (focus)="setupFilter('name')" />
</th>
</ng-container>
或更复杂的示例,通过每列过滤动态创建标题行:
<table mat-table [dataSource]="dataSource">
<ng-container *ngFor="let filterCol of ['names', 'age', 'address']">
<ng-container matColumnDef="filterCol">
<th mat-header-cell *matHeaderCellDef>
<input (keyup)="applyFilter($event.target.value)" (focus)="setupFilter(filterCol)"/>
</th>
</ng-container>
</ng-container>
<tr mat-header-row *matHeaderRowDef="['names', 'age', 'address']"></tr>
</table>
请注意,您不能具有多个具有相同键的标题行,因此这行不通:
<tr mat-header-row *matHeaderRowDef="['names', 'age', 'address']"></tr>
<tr mat-header-row *matHeaderRowDef="['names', 'age', 'address']"></tr>
答案 4 :(得分:0)
如果您要查找范围谓词以过滤一个属性的值范围:
applyRangePredicate() {
this.datasource.filterPredicate = (data:
{id: string}, filter: string) => {
let searchlist = JSON.parse(filter);
var found = false
searchlist.forEach(item => {
if (data.id.indexOf(item) !== -1)
found = true
})
return found
}
}
然后分配一个json字符串以将过滤后的数据流式传输到UI
this.applyRangePredicate()
this.datasource.filter = JSON.stringify(string[])
答案 5 :(得分:0)
您必须重写dataSource的filterPredicate。
您想指定过滤器将数据应用于哪些属性:-
SELECT q.firstname, q.surname, q.dob, p1.personid, m.membershipid
FROM
(SELECT
p.firstname,p.surname,p.dob, count(*) as cnt
FROM
person p
GROUP BY
p.firstname,p.surname,p.dob
HAVING COUNT(1) > 1) as q
INNER JOIN person p1 ON q.firstname=p1.firstname AND q.surname=p1.surname AND q.dob=p1.dob
INNER JOIN person_membership pm ON p1.personid=pm.personid
INNER JOIN membership m ON pm.memberid = m.membershipid
WHERE pm.personstatus = 'A' AND m.memstatus = 'A'
答案 6 :(得分:0)
要在Naresh's answer上进行扩展,以下HTML代码段显示了如何在同一列中进行排序和过滤,以及如何使用小“ x”按钮清除过滤条件:
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
<mat-form-field >
<mat-label>Search Description</mat-label>
<input matInput
[formControl]="descriptionFilter"
(click)="$event.stopPropagation()">
<button mat-button
*ngIf="descriptionFilter.value"
matSuffix mat-icon-button
aria-label="Clear"
(click)="descriptionFilter.setValue('')">
<mat-icon>close</mat-icon>
</button>
</mat-form-field>
</th>
<td mat-cell *matCellDef="let assessment">
{{assessment?.description}} </td>
</ng-container>
答案 7 :(得分:0)
使用 filterPredicate 使用 customFilter()
覆盖过滤器逻辑演示Link
来源Link
...
ngOnInit() {
this.getRemoteData();
// Overrride default filter behaviour of Material Datatable
this.dataSource.filterPredicate = this.createFilter();
}
...
// Custom filter method fot Angular Material Datatable
createFilter() {
let filterFunction = function (data: any, filter: string): boolean {
let searchTerms = JSON.parse(filter);
let isFilterSet = false;
for (const col in searchTerms) {
if (searchTerms[col].toString() !== '') {
isFilterSet = true;
} else {
delete searchTerms[col];
}
}
let nameSearch = () => {
let found = false;
if (isFilterSet) {
for (const col in searchTerms) {
searchTerms[col].trim().toLowerCase().split(' ').forEach(word => {
if (data[col].toString().toLowerCase().indexOf(word) != -1 && isFilterSet) {
found = true
}
});
}
return found
} else {
return true;
}
}
return nameSearch()
}
return filterFunction
}
答案 8 :(得分:0)
这对我有帮助:
https://www.freakyjolly.com/angular-material-table-custom-filter-using-select-box/#.YB4GBugzbIU
如果你想在所有选择字段上都有“and”条件,那么有一个数组 - foundThisField[], 而不是 boolean found = true/false
例如。 foundThisField : number = []
然后如果找到字段/列/属性,则执行 foundThisField.push(1) 或 foundThisField.push(0)
最后,返回 foundThisField.includes(0)?false:true