Angular Material表格列级搜索过滤器实现技术求助
实现Angular Material动态数据表格的列级搜索过滤器
1. 组件内管理筛选状态与数据源
在组件类中维护列筛选值的存储对象,结合BehaviorSubject实现响应式的筛选逻辑:
import { Component, OnInit } from '@angular/core'; import { BehaviorSubject, combineLatest } from 'rxjs'; import { map } from 'rxjs/operators'; import { MatTableDataSource } from '@angular/material/table'; // 动态列定义接口 interface ColumnDef { key: string; // 对应数据对象的属性名 label: string; // 表头显示文本 } // 数据项通用接口(替换为你的实际数据结构) interface TableDataItem { [key: string]: any; } @Component({ selector: 'app-filterable-dynamic-table', templateUrl: './filterable-dynamic-table.component.html', styleUrls: ['./filterable-dynamic-table.component.css'] }) export class FilterableDynamicTableComponent implements OnInit { columns: ColumnDef[] = []; // 动态列配置,从API或本地配置获取 rawData$ = new BehaviorSubject<TableDataItem[]>([]); // 原始数据源 columnFilters$ = new BehaviorSubject<{[key: string]: string}>({}); // 各列筛选值 filteredData$ = combineLatest([this.rawData$, this.columnFilters$]).pipe( map(([data, filters]) => this.applyFilters(data, filters)) ); dataSource = new MatTableDataSource<TableDataItem>(); ngOnInit(): void { // 调用API获取数据和列定义 this.loadTableData(); // 订阅过滤后的数据更新表格 this.filteredData$.subscribe(filtered => { this.dataSource.data = filtered; }); } loadTableData(): void { // 替换为你的实际API请求逻辑 // 示例列定义 this.columns = [ { key: 'id', label: 'ID' }, { key: 'username', label: '用户名' }, { key: 'email', label: '邮箱' }, { key: 'role', label: '角色' } ]; // 示例API返回数据 const mockApiData = [ { id: 1, username: 'zhangsan', email: 'zhangsan@demo.com', role: '管理员' }, { id: 2, username: 'lisi', email: 'lisi@demo.com', role: '普通用户' }, { id: 3, username: 'wangwu', email: 'wangwu@demo.com', role: '管理员' } ]; this.rawData$.next(mockApiData); } // 核心筛选逻辑 applyFilters(data: TableDataItem[], filters: {[key: string]: string}): TableDataItem[] { return data.filter(item => { return Object.keys(filters).every(key => { const filterVal = filters[key].toLowerCase().trim(); if (!filterVal) return true; // 无筛选值时跳过该列过滤 const itemVal = item[key]?.toString().toLowerCase() || ''; return itemVal.includes(filterVal); }); }); } // 筛选值变更时更新筛选状态 onFilterInput(columnKey: string, inputVal: string): void { const currentFilters = this.columnFilters$.value; this.columnFilters$.next({ ...currentFilters, [columnKey]: inputVal }); } }
2. 模板中添加列级筛选输入框
在表头上方为每个动态列添加筛选输入框,绑定筛选值与变更事件:
<div class="mat-elevation-z8"> <!-- 列筛选栏 --> <div class="filter-bar"> <ng-container *ngFor="let column of columns"> <mat-form-field appearance="fill" class="filter-input"> <mat-label>{{column.label}}</mat-label> <input matInput (input)="onFilterInput(column.key, $event.target.value)" placeholder="输入关键词筛选"> </mat-form-field> </ng-container> </div> <!-- 动态表格主体 --> <table mat-table [dataSource]="dataSource"> <ng-container *ngFor="let column of columns" [matColumnDef]="column.key"> <th mat-header-cell *matHeaderCellDef>{{column.label}}</th> <td mat-cell *matCellDef="let row">{{row[column.key]}}</td> </ng-container> <tr mat-header-row *matHeaderRowDef="columns.map(col => col.key)"></tr> <tr mat-row *matRowDef="let row; columns: columns.map(col => col.key)"></tr> </table> </div>
3. 样式优化(可选)
添加CSS让筛选栏布局更合理:
.filter-bar { display: flex; gap: 16px; padding: 16px; flex-wrap: wrap; } .filter-input { min-width: 220px; }
关键注意事项
- 动态列的
key必须与数据对象的属性名完全匹配,否则筛选逻辑无法读取对应字段 - 筛选逻辑默认忽略大小写,可根据需求调整匹配规则(如精确匹配、前缀匹配等)
- 若数据量较大,可考虑添加防抖处理减少筛选触发频率
内容的提问来源于stack exchange,提问作者juniorangulardeveloper
相关产品推荐
相关产品推荐

