如何在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
相关产品推荐
相关产品推荐

