我目前正在使用材质2表来显示某些数据的组件。我需要能够编写自定义过滤器操作(例如价格> 1)并组合多个过滤器。为了完成这项工作,我写了一个自定义filterPredicate:
customFilterPredicate(data: Coin, filters: Predicate[]): boolean {
var operators = {
'>=': function(a, b){
return +a >= +b
},
'<=': function(a, b){
return +a <= +b
}
}
if(filters.length == 0) return true;
let res = false;
for(var i = 0; i < filters.length; i++){
let conditionMet = operators[filters[i].op](data[filters[i].columnName], filters[i].val);
if(conditionMet) {
res = true;
} else {
res = false;
break;
}
}
return res
}
谓词类型的接口:
export interface Predicate {
field: columnName
op: string;
val: number;
visible: boolean;
}
customFilterPredicate遍历作为参数传递的所有过滤器,如果满足所有条件则返回true,如果一个或多个条件未满足则返回false。
现在我使用此函数通过服务获取表的数据,设置我的dataSource并替换dataSource的filterPredicate:
setData(){
return new Promise((resolve, reject) => {
return this.coinService.getCoins()
.subscribe(coins => {
resolve(coins)
})
})
.then((data: Coin[]) => {
this.dataSource = new MatTableDataSource<Coin>(data);
this.dataSource.filterPredicate = this.customPredicate;
})
}
有趣的是,当我使用它时过滤工作,但它总是抛出一个错误,说我不能用我的自定义替换filterPredicate,因为它希望filter参数是一个字符串。
所以我的问题是,如何在不重写材料2包中的函数的情况下将this.dataSource.filterPredicate替换为我的。有没有办法在打字稿中这样做?
如果有人知道为什么这样可行,尽管抛出了错误,哈哈会感兴趣
答案 0 :(得分:3)
目前不支持此功能,但Github上有一个开放的feature request。它被添加到功能列表中,因此可能值得关注。
在此问题中,建议使用过滤器创建您自己的DataSource
,该过滤器接受数组而不是字符串。请查看扩展MatTableDataSource类的DataSource。
答案 1 :(得分:3)
作为解决方法,可以在设置filterPredicate时使用bind():
this.dataSource.filterPredicate = this.customFilterPredicate.bind(this);
然后,在我的情况下,您可以访问局部变量:
customFilterPredicate(data: Area, filter: string): boolean {
return this.filterMatchesString(JSON.stringify(data), this.searchFilter) &&
this.filterMatchesString(data.Area, this.areaFilter) &&
this.filterMatchesString(data.Abbreviation, this.abbreviationFilter);
}
在您的情况下,它将是谓词数组。但是,每当任何谓词发生更改时,您都需要更新filter的值,只有在更改发生时才重新应用该filter。
filterChange() {
this.dataSource.filter = this._searchFilter + this._areaFilter + this._abbreviationFilter;
}