如何在不修改源数据的前提下对Mat Table进行数据筛选
Angular Mat Table 基于显示文本的筛选与排序实现
要实现不修改源数据,仅基于表格显示文本进行筛选和排序,需要重写MatTableDataSource的筛选逻辑和排序数据访问器,具体实现如下:
1. 自定义筛选逻辑
重写filterPredicate,将原始字段转换为表格显示的文本后再参与筛选匹配:
// 初始化数据源后配置筛选器 this.dataSource.filterPredicate = (data: any, filter: string) => { // 转换IsActive字段为显示文本 const isActiveText = data.IsActive === 1 ? 'Activated' : 'Deactivated'; // 可扩展其他需要转换的字段(比如IsVerified) const isVerifiedText = data.IsVerified === 1 ? 'Verified' : 'Unverified'; // 拼接所有需要参与筛选的字段文本,统一转为小写后匹配 const searchContent = `${data.FirstName} ${data.MobileNumber} ${data.EmailAddress} ${isVerifiedText} ${isActiveText}`.toLowerCase(); return searchContent.includes(filter.toLowerCase()); };
2. 自定义排序逻辑
通过sortingDataAccessor指定排序时使用的显示文本,而非原始数值:
// 初始化数据源后配置排序访问器 this.dataSource.sortingDataAccessor = (data: any, sortHeaderId: string) => { switch (sortHeaderId) { case 'IsActive': // 返回显示文本用于排序 return data.IsActive === 1 ? 'Activated' : 'Deactivated'; case 'IsVerified': // 同理处理其他需要按显示文本排序的字段 return data.IsVerified === 1 ? 'Verified' : 'Unverified'; default: // 其他字段使用原始值排序 return data[sortHeaderId] as string | number; } };
3. 完整TS代码示例
import { ViewChild } from '@angular/core'; import { MatTableDataSource } from '@angular/material/table'; import { MatSort } from '@angular/material/sort'; import { MatPaginator } from '@angular/material/paginator'; // ...组件类内部 displayedColumns: string[] = ['FirstName', 'MobileNumber', 'EmailAddress', 'IsVerified', 'IsActive', 'action']; @ViewChild(MatSort) sort!: MatSort; @ViewChild(MatPaginator) paginator!: MatPaginator; dataSource = new MatTableDataSource<any>(); ngAfterViewInit() { // 假设response['Data']是你的接口返回数据源 this.dataSource.data = response['Data']; this.dataSource.sort = this.sort; this.dataSource.paginator = this.paginator; // 配置自定义筛选器 this.dataSource.filterPredicate = (data: any, filter: string) => { const isActiveText = data.IsActive === 1 ? 'Activated' : 'Deactivated'; const isVerifiedText = data.IsVerified === 1 ? 'Verified' : 'Unverified'; const searchContent = `${data.FirstName} ${data.MobileNumber} ${data.EmailAddress} ${isVerifiedText} ${isActiveText}`.toLowerCase(); return searchContent.includes(filter.toLowerCase()); }; // 配置自定义排序访问器 this.dataSource.sortingDataAccessor = (data: any, sortHeaderId: string) => { switch (sortHeaderId) { case 'IsActive': return data.IsActive === 1 ? 'Activated' : 'Deactivated'; case 'IsVerified': return data.IsVerified === 1 ? 'Verified' : 'Unverified'; default: return data[sortHeaderId] as string | number; } }; } // 搜索输入框的筛选触发方法 applyFilter(event: Event) { const filterValue = (event.target as HTMLInputElement).value; this.dataSource.filter = filterValue.trim().toLowerCase(); }
4. HTML补充(可选搜索框)
如果需要搜索功能,添加输入框绑定筛选方法:
<div class="filter-bar"> <input matInput (input)="applyFilter($event)" placeholder="搜索姓名、状态等"> </div> <!-- 保留你原有的表格列定义 --> <ng-container matColumnDef="IsActive"> <th mat-header-cell *matHeaderCellDef mat-sort-header> Status </th> <td mat-cell *matCellDef="let element" (click)="theData(element.IsActive)"> {{ element.IsActive === 1 ? 'Activated': 'Deactivated' }} </td> </ng-container>
效果说明
- 筛选:搜索"Activated"会匹配所有
IsActive=1的行,搜索"Deactivated"匹配IsActive=0的行; - 排序:点击Status列的排序按钮,会按"Activated"、"Deactivated"的字母顺序排序,而非原始数值的1、0顺序;
- 全程无需修改源数据,仅在筛选和排序阶段做临时文本转换。
内容的提问来源于stack exchange,提问作者SANYAM CHAURASIA
相关产品推荐
相关产品推荐

