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

如何在Angular Material mat-table单列实现多复选框筛选后二次搜索

实现思路

  • 核心是分层过滤逻辑:先执行列级复选框过滤,再对过滤后的结果执行全局/指定字段的关键词搜索
  • 不要直接修改mat-table的原生filterPredicate,而是自定义过滤逻辑,维护两个数据源变量:originalDataSource(存储全量原始数据,永远不直接修改,作为所有过滤的基准)、tableDataSource(存储经过两层过滤后渲染到表格的数据源实例)
  • 复选框筛选逻辑:为Balls列的所有可选颜色维护一个选中集合selectedColors,每次选中状态变更时,先从originalDataSource过滤出所有balls字段属于selectedColors的条目,得到第一阶段过滤结果
  • 二次搜索逻辑:监听搜索框输入事件,对第一阶段过滤得到的结果做关键词匹配,匹配范围可根据需求指定为全字段或特定字段,最终结果赋值给mat-table绑定的dataSource
  • 若要保留mat-table的分页、排序能力,需要把过滤后的结果赋值给MatTableDataSource实例,而不是普通数组

提示:如果需要把复选框筛选放到列头的下拉菜单里,配合mat-menu组件实现即可,过滤逻辑不需要修改,只需要把复选框组放到mat-menu的模板中即可实现你需要的交互样式。

简易实现示例

1. 依赖模块导入

首先确保在对应模块中导入所需的Angular Material依赖:

import { NgModule } from '@angular/core';
import { MatTableModule } from '@angular/material/table';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatInputModule } from '@angular/material/input';
import { MatFormFieldModule } from '@angular/material/form-field';
import { FormsModule } from '@angular/forms';
// 其他公共模块按需导入

2. 组件逻辑代码

import { Component, OnInit } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';

// 定义表格行数据结构
interface TableRow {
  id: number;
  itemName: string;
  balls: string; // 存储球的颜色值,如'red'/'blue'
  // 其他业务字段按需添加
}

@Component({
  selector: 'app-filter-table',
  templateUrl: './filter-table.component.html',
  styleUrls: ['./filter-table.component.css']
})
export class FilterTableComponent implements OnInit {
  // 表格显示列配置
  displayedColumns: string[] = ['id', 'itemName', 'balls'];
  // 原始全量数据,作为所有过滤的基准,不会被直接修改
  originalData: TableRow[] = [];
  // 绑定到表格的数据源实例
  tableDataSource = new MatTableDataSource<TableRow>();

  // Balls列可选颜色配置
  colorOptions = ['红', '蓝', '黄', '绿', '紫'];
  // 已选中的颜色集合,默认全选
  selectedColors = new Set<string>(this.colorOptions);
  // 二次搜索关键词
  searchKey = '';

  ngOnInit(): void {
    // 模拟请求后端获取原始数据
    this.originalData = [
      {id: 1, itemName: '测试条目1', balls: '红'},
      {id: 2, itemName: '测试条目2', balls: '蓝'},
      {id: 3, itemName: '测试条目3', balls: '红'},
      {id: 4, itemName: '测试条目4', balls: '黄'},
      {id: 5, itemName: '测试条目5', balls: '绿'},
      // 更多测试数据按需添加
    ];
    // 初始化时执行一次过滤
    this.runFilter();
  }

  // 统一过滤入口,复选框状态变更、搜索关键词变更时都调用该方法
  runFilter(): void {
    // 第一步:执行Balls列复选框过滤
    let result = this.originalData.filter(row => this.selectedColors.has(row.balls));

    // 第二步:执行二次关键词搜索,示例匹配itemName字段,可按需扩展多字段匹配
    if (this.searchKey.trim()) {
      const key = this.searchKey.trim().toLowerCase();
      result = result.filter(row => row.itemName.toLowerCase().includes(key));
      // 如需多字段匹配可扩展为:
      // return row.itemName.toLowerCase().includes(key) || row.xxx.toLowerCase().includes(key)
    }

    // 将最终过滤结果赋值给表格数据源
    this.tableDataSource.data = result;
  }

  // 复选框选中状态变更处理
  onColorCheckChange(color: string, isChecked: boolean): void {
    isChecked ? this.selectedColors.add(color) : this.selectedColors.delete(color);
    this.runFilter();
  }
}

3. 组件模板代码

<!-- 二次搜索框 -->
<mat-form-field appearance="outline" style="width: 300px; margin-bottom: 16px;">
  <mat-label>搜索结果</mat-label>
  <input matInput [(ngModel)]="searchKey" (input)="runFilter()" placeholder="输入关键词">
</mat-form-field>

<!-- Balls列复选框筛选区 -->
<div style="margin-bottom: 16px;">
  <span>Balls列颜色筛选:</span>
  <mat-checkbox 
    *ngFor="let color of colorOptions"
    [checked]="selectedColors.has(color)"
    (change)="onColorCheckChange(color, $event.checked)"
    style="margin-right: 12px;"
  >
    {{color}}
  </mat-checkbox>
</div>

<!-- 表格主体 -->
<table mat-table [dataSource]="tableDataSource">
  <ng-container matColumnDef="id">
    <th mat-header-cell *matHeaderCellDef>序号</th>
    <td mat-cell *matCellDef="let element"> {{element.id}} </td>
  </ng-container>

  <ng-container matColumnDef="itemName">
    <th mat-header-cell *matHeaderCellDef>条目名称</th>
    <td mat-cell *matCellDef="let element"> {{element.itemName}} </td>
  </ng-container>

  <ng-container matColumnDef="balls">
    <th mat-header-cell *matHeaderCellDef>Balls</th>
    <td mat-cell *matCellDef="let element"> {{element.balls}} </td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

内容的提问来源于stack exchange,提问作者gtXs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 03:24:08