You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不修改源数据的前提下对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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 16:25:05