Angular 5中如何用MatTableDataSource实现自定义过滤?求filterPredicate示例
在Angular 5中使用MatTableDataSource实现自定义过滤
别担心,我会结合官方文档提到的filterPredicate给你一个清晰的示例,一步步带你实现自定义过滤功能。
核心概念回顾
filterPredicate是MatTableDataSource的核心属性,它本质是一个回调函数,官方定义的签名是:
filterPredicate: ((data: T, filter: string) => boolean)
它会遍历表格的每一条数据,根据你传入的过滤字符串,返回true(显示这条数据)或false(隐藏这条数据),判断逻辑完全由你定制。
完整实现示例
假设我们有一个用户表格,数据模型包含id、name、email三个字段,我们要实现同时根据姓名和邮箱进行模糊过滤,且忽略大小写差异。
1. 定义数据模型(组件类中)
先创建你的数据接口:
export interface User { id: number; name: string; email: string; }
2. 初始化数据源并设置自定义filterPredicate
在组件类中:
import { Component, OnInit } from '@angular/core'; import { MatTableDataSource } from '@angular/material'; import { User } from './user.model'; @Component({ selector: 'app-user-table', templateUrl: './user-table.component.html', styleUrls: ['./user-table.component.css'] }) export class UserTableComponent implements OnInit { displayedColumns: string[] = ['id', 'name', 'email']; dataSource: MatTableDataSource<User>; // 模拟测试数据 users: User[] = [ {id: 1, name: 'Alice Smith', email: 'alice@example.com'}, {id: 2, name: 'Bob Johnson', email: 'bob@company.org'}, {id: 3, name: 'Charlie Brown', email: 'charlie@test.net'} ]; ngOnInit() { this.dataSource = new MatTableDataSource(this.users); // 自定义filterPredicate逻辑 this.dataSource.filterPredicate = (data: User, filter: string) => { // 将过滤字符串转为小写,统一匹配规则 const filterLower = filter.toLowerCase(); // 判断姓名或邮箱是否包含过滤字符串(忽略大小写) return data.name.toLowerCase().includes(filterLower) || data.email.toLowerCase().includes(filterLower); }; } // 处理输入框的过滤事件 applyFilter(event: Event) { const filterValue = (event.target as HTMLInputElement).value; this.dataSource.filter = filterValue.trim().toLowerCase(); } }
3. 模板中的表格与过滤输入框
在user-table.component.html中:
<!-- 过滤输入框 --> <mat-form-field> <input matInput (keyup)="applyFilter($event)" placeholder="过滤姓名/邮箱"> </mat-form-field> <!-- 表格 --> <table mat-table [dataSource]="dataSource" class="mat-elevation-z8"> <!-- ID列 --> <ng-container matColumnDef="id"> <th mat-header-cell *matHeaderCellDef> ID </th> <td mat-cell *matCellDef="let user"> {{user.id}} </td> </ng-container> <!-- 姓名列 --> <ng-container matColumnDef="name"> <th mat-header-cell *matHeaderCellDef> 姓名 </th> <td mat-cell *matCellDef="let user"> {{user.name}} </td> </ng-container> <!-- 邮箱列 --> <ng-container matColumnDef="email"> <th mat-header-cell *matHeaderCellDef> 邮箱 </th> <td mat-cell *matCellDef="let user"> {{user.email}} </td> </ng-container> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table>
扩展:针对特定字段过滤
如果你只想针对单个字段(比如只过滤姓名),只需要修改filterPredicate的逻辑即可:
this.dataSource.filterPredicate = (data: User, filter: string) => { return data.name.toLowerCase().includes(filter.toLowerCase()); };
关键注意点
- 每次调用
this.dataSource.filter = XXX时,Angular Material会自动触发filterPredicate遍历所有数据。 - 建议将过滤字符串统一转为小写(或大写),避免大小写敏感的问题。
- 你可以在
filterPredicate中加入任何复杂逻辑,比如判断数值范围、多条件组合等,完全根据业务需求定制。
内容的提问来源于stack exchange,提问作者Tanvi Shah
相关产品推荐
相关产品推荐

