2

我目前正在研究一个使用材料 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;
    })
  }

有趣的是,当我使用它时过滤器会起作用,但它总是抛出一个错误,说我不能用我的自定义过滤器替换过滤器谓词,因为它期望过滤器参数是一个字符串。

所以我的问题是,如何在不重写材料2包中的函数的情况下用我的this.dataSource.filterPredicate替换。有没有办法在打字稿中做到这一点?

如果有人知道为什么会这样,尽管抛出错误,那会很有趣,哈哈

4

2 回答 2

4

目前不支持此功能,但 Github 上有一个开放的功能请求。它已添加到功能列表中,因此可能值得关注。

DataSource在这个问题中,建议使用接受数组而不是字符串的过滤器创建自己的过滤器。看看扩展DataSource类的MatTableDataSource 。

于 2018-04-17T21:55:06.583 回答
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);
}

在您的情况下,它将是谓词数组。但是,每当任何谓词更改时,您都需要更新过滤器的值,只有在更改时才会重新应用过滤器。

filterChange() {
    this.dataSource.filter = this._searchFilter + this._areaFilter + this._abbreviationFilter;
}
于 2018-09-17T10:45:54.373 回答