如何为Angular mat-table添加表头下方的筛选行?
为Mat-Table添加表头下方筛选行的实现方案
问题说明
现有支持表头拖拽排序的Mat-Table,需在表头行下方添加对应列的筛选行,且不同列的筛选控件类型不同(数字输入框、自动补全单选框、多选下拉框),无法直接用统一循环渲染。
实现步骤
1. 扩展列配置,增加筛选类型标识
修改组件中的列配置数组,为每个列添加type字段用于区分筛选控件类型,同时初始化筛选表单(需确保项目已导入ReactiveFormsModule):
tableDisplayedColumns: string[] = ['param1', 'param2', 'param3']; columns: any[] = [ { name: 'param1', title: 'Param1', type: 'numberInput' }, { name: 'param2', title: 'Param2', type: 'autocomplete' }, { name: 'param3', title: 'Param3', type: 'multiselect' } ]; // 初始化筛选表单 filterForm = new FormGroup({ filterParam1: new FormControl(''), filterParam2: new FormControl(''), filterParam3: new FormControl([]) });
2. 在列定义中添加筛选单元格模板
在每个matColumnDef的ng-container内,新增筛选专用的mat-cell模板,通过ngSwitch根据列的type渲染对应控件:
<mat-table class="table" cdkDropList cdkDropListOrientation="horizontal" (cdkDropListDropped)="tableDrop($event)" [dataSource]="tableDataSource"> <ng-container *ngFor="let column of columns; let i = index" [matColumnDef]="column.name"> <!-- 原表头单元格 --> <mat-header-cell *matHeaderCellDef cdkDrag cdkDragLockAxis="x" cdkDragBoundary="mat-header-row"> {{ column.title }} </mat-header-cell> <!-- 新增筛选单元格 --> <mat-cell *matCellDef="let _"> <ng-container [ngSwitch]="column.type"> <!-- 数字输入框筛选 --> <ng-container *ngSwitchCase="'numberInput'"> <mat-form-field class="filterField"> <input matInput type="number" (keydown)="updateManualPage(1)" placeholder="Filter za {{ column.title }}" formControlName="filterParam1"> </mat-form-field> </ng-container> <!-- 自动补全单选筛选 --> <ng-container *ngSwitchCase="'autocomplete'"> <mat-form-field class="filterField"> <input matInput (keydown)="updateManualPage(1)" placeholder="Filter za {{ column.title }}" formControlName="filterParam2" [matAutocomplete]="autoSingleSelect"> <mat-autocomplete #autoSingleSelect="matAutocomplete" class="filterSelect" panelClass="filterSelect"> <mat-option *ngFor="let option of dropdownSingleFilteredOptions | async" [value]="option.param2"> {{option.param2}} </mat-option> </mat-autocomplete> </mat-form-field> </ng-container> <!-- 多选下拉筛选 --> <ng-container *ngSwitchCase="'multiselect'"> <mat-form-field class="filterField"> <mat-select class="filterMultiselect" placeholder="Filter za {{ column.title }}" formControlName="filterParam3" multiple panelClass="filterMultiselect"> <mat-option *ngFor="let option of tableDataSource.data" [value]="option.param3"> {{option.param3}} </mat-option> </mat-select> </mat-form-field> </ng-container> </ng-container> </mat-cell> <!-- 原数据单元格 --> <mat-cell *matCellDef="let element"> {{ element[column.name] }} </mat-cell> </ng-container> <!-- 原表头行 --> <mat-header-row class="tableHeader" *matHeaderRowDef="tableDisplayedColumns" #tableHeaderRow> </mat-header-row> <!-- 新增筛选行 --> <mat-row class="filterRow" *matRowDef="let _; columns: tableDisplayedColumns;" [formGroup]="filterForm"> </mat-row> <!-- 原数据行 --> <mat-row class="tableRow" *matRowDef="let row; columns: tableDisplayedColumns;" [class.selected-row]="tableSelectedRows.has(row)" (click)="selectUnselectRow(row)"> </mat-row> </mat-table>
3. 样式调整(可选)
给筛选行添加样式,确保控件与列对齐:
.filterRow { background-color: #f5f5f5; } .filterField { width: 100%; margin: 4px 0; }
关键说明
- 通过扩展列配置的
type字段,实现不同列筛选控件的差异化渲染,同时保留循环渲染的便利性 - 筛选行通过独立的
*matRowDef定义,与表头行、数据行分离,不影响原有表格逻辑 - 使用响应式表单管理筛选控件的值,便于后续筛选逻辑的统一处理
内容的提问来源于stack exchange,提问作者Baltr
相关产品推荐
相关产品推荐

