Angular 材质表 filterPredicate

Posted

技术标签:

【中文标题】Angular 材质表 filterPredicate【英文标题】:Angular Material Table filterPredicate 【发布时间】:2018-07-06 07:20:42 【问题描述】:

我正在尝试通过特定对象键过滤一组数据 例如:我有一组技能,我想查看第 2 级的所有技能。

我已通读文档this GitHub example 和this other question,但我找不到如何使用用户输入通过对象键进行过滤的实际示例。到目前为止,当用户点击技能级别时,什么都没有发生。

现在我的 html 看起来像:

<mat-button-toggle-group #group="matButtonToggleGroup"
    class="margin-1" (change)=toggleSkillLevel(group.value)>

  <mat-button-toggle value="0">
    0
  </mat-button-toggle>

  <mat-button-toggle value="1">
    1
  </mat-button-toggle>

  <mat-button-toggle value="2">
    2
  </mat-button-toggle>

  <mat-button-toggle value="all">
    ALL
  </mat-button-toggle>

</mat-button-toggle-group>

 dataSource.filteredData 

我的 TS 看起来像:

 import  Skill, SKILL_DATA  from '../data/skills-details';

...
...

  toggleSkillLevel(level)
    console.log('Only show level ' + level + ' skills...');
    this.dataSource.filterPredicate =
            (data: Skill, filter: string) => data.level == level;
  

【问题讨论】:

这能回答你的问题吗? custom filter in mat-table 【参考方案1】:

通过设置filterPredicate,您只需定义在给定过滤器值时应如何将过滤器值应用于您的数据。这只是过滤器功能的定义,您实际上并没有使用它来应用过滤器。 因此,您只需定义一次,这可能发生在 ngOnInit 中。

ngOnInit() 
  this.dataSource.filterPredicate =
      (data: Skill, filter: string) => !filter || data.level == filter;

要使用实际值应用过滤器,您需要设置dataSource.filter,例如:

toggleSkillLevel(level) 
  this.dataSource.filter = level;

【讨论】:

这个答案帮助我解决了这个问题。而不是data.(myObj) == level 我把data.(myObj) == filter 你还知道如何在 filterPredicate 中访问this @AGoranov 使用箭头函数而不是我在示例中所做的匿名函数。然后this 将与您的组件中的相同。 @KimKern 因为我的函数很长,所以它是这样完成的:this.dataSource.filterPredicate = this.filterPredicate;。参数和你的一样。 @AGoranov 改为:this.dataSource.filterPredicate = (data: Skill, filter: string) =&gt; this.filterPredicate(data, filter);.【参考方案2】:

只是想在 Kim Kern 的回答中添加一个补充。

如果您应用此方法并开始收到如下错误:

TypeError: Cannot read property 'filter' of null
at MatTableDataSource._filterData (http://localhost.satin.lo:7000/vendor.js:88312:18)
at MapSubscriber.project (http://localhost.satin.lo:7000/vendor.js:88291:89)
at MapSubscriber._next (http://localhost.satin.lo:7000/vendor.js:141164:35)
at MapSubscriber.next (http://localhost.satin.lo:7000/vendor.js:137246:18)
at CombineLatestSubscriber.notifyNext (http://localhost.satin.lo:7000/vendor.js:137998:34)
at InnerSubscriber._next (http://localhost.satin.lo:7000/vendor.js:136528:21)
at InnerSubscriber.next (http://localhost.satin.lo:7000/vendor.js:137246:18)
at BehaviorSubject.next (http://localhost.satin.lo:7000/vendor.js:137030:25)
at BehaviorSubject.next (http://localhost.satin.lo:7000/vendor.js:136499:15)
at MatTableDataSource.set filter [as filter] (http://localhost.satin.lo:7000/vendor.js:88238:22)

此错误是由于在您调用 this.dataSource.filter = xyz; 时您的 dataSource.datanull 的结果

我从父组件 ajax 调用中设置了我的数据源:

@Input() set items(data: IItem[]) 
     this.dataSource.data = data;

observable 的默认值是null。所以我通过一个简单的空检查解决了这个问题:

@Input() set items(data: IItem[]) 
    if(data)
        this.dataSource.data = data;
    

【讨论】:

以上是关于Angular 材质表 filterPredicate的主要内容,如果未能解决你的问题,请参考以下文章

在 Angular 材质表上调用 renderRows()

Angular > 在材质表中显示列和行

编辑 Angular 材质表单元格填充

如何将 json 数据与 Angular 材质表绑定以创建动态表?

在 Angular 材质表中使用省略号

角度材质表,对象作为数据源