如何基于下拉框多项选择筛选Angular Material表格结果?
Angular Material Table 多下拉框联合筛选实现方案
我来给你捋捋怎么实现两个下拉框的联合筛选,完全贴合你说的「同时匹配两个条件,不满足则无结果」的需求:
1. 先准备组件变量与模板
首先在组件类里定义两个变量存储下拉框的选中值,以及生成下拉框选项的集合:
import { MatTableDataSource } from '@angular/material/table'; // 假设你的数据接口是这样的 interface PeriodicElement { number: number; name: string; symbol: string; weight: number; } export class YourComponent { dataSource = new MatTableDataSource<PeriodicElement>(YOUR_DATA); // 替换成你的数据源 selectedNumber: number | null = null; selectedElement: string | null = null; numberOptions: number[] = []; elementOptions: string[] = []; ngOnInit() { // 从数据源提取唯一的原子序数和元素名称,作为下拉框选项 this.numberOptions = [...new Set(this.dataSource.data.map(item => item.number))].sort(); this.elementOptions = [...new Set(this.dataSource.data.map(item => item.name))].sort(); // 初始化筛选规则 this.setupFilterPredicate(); } }
然后在模板里添加两个mat-select下拉框,并绑定选中值:
<!-- 原子序数下拉框 --> <mat-form-field appearance="fill" class="mr-4"> <mat-label>原子序数</mat-label> <mat-select [(value)]="selectedNumber" (selectionChange)="applyFilter()"> <mat-option [value]="null">全部</mat-option> <mat-option *ngFor="let num of numberOptions" [value]="num">{{num}}</mat-option> </mat-select> </mat-form-field> <!-- 元素名称下拉框 --> <mat-form-field appearance="fill"> <mat-label>元素名称</mat-label> <mat-select [(value)]="selectedElement" (selectionChange)="applyFilter()"> <mat-option [value]="null">全部</mat-option> <mat-option *ngFor="let name of elementOptions" [value]="name">{{name}}</mat-option> </mat-select> </mat-form-field> <!-- 你的Material Table代码 --> <table mat-table [dataSource]="dataSource"> <!-- 表格列定义... --> </table>
2. 配置联合筛选规则
核心是修改MatTableDataSource的filterPredicate,让它同时判断两个下拉框的条件:
private setupFilterPredicate() { this.dataSource.filterPredicate = (data: PeriodicElement, filter: string) => { // 解析传递的筛选条件 const filterConditions = JSON.parse(filter); const { targetNumber, targetElement } = filterConditions; // 原子序数匹配逻辑:如果没选则跳过判断,选了则严格匹配 let matchesNumber = true; if (targetNumber !== null) { matchesNumber = data.number === targetNumber; } // 元素名称匹配逻辑:同理,没选则跳过,选了则严格匹配 let matchesElement = true; if (targetElement !== null) { matchesElement = data.name === targetElement; } // 两个条件都满足才返回true return matchesNumber && matchesElement; }; }
3. 触发筛选的方法
当下拉框选中值变化时,把两个条件打包成JSON字符串传递给数据源的filter属性,触发筛选:
applyFilter() { const filterPayload = { targetNumber: this.selectedNumber, targetElement: this.selectedElement }; // 通过修改filter值触发筛选逻辑 this.dataSource.filter = JSON.stringify(filterPayload); }
效果说明
- 当你选择「1」和「氢」时,只有同时满足
number=1且name=氢的记录会被保留 - 当你选择「8」和「氢」时,因为没有记录同时符合两个条件,表格会显示空结果
- 如果只选其中一个下拉框,另一个选「全部」,则只会按选中的那个条件筛选
内容的提问来源于stack exchange,提问作者Euridice01
相关产品推荐
相关产品推荐

