Angular Material表格筛选功能失效无报错,输入条件无过滤效果
筛选失效问题根因与修复方案
你现在遇到的筛选无反应,完全是配置错位导致的,没有复杂的逻辑问题,逐个修正即可:
具体错位问题
- 数据源绑定错位:你在TS中创建了支持筛选的
MatTableDataSource实例dataSour,但HTML里的表格绑定的是最原始的数组dataSource。筛选操作是给dataSour设置filter值,和表格实际读取的原始数组没有任何关联,自然不会触发过滤效果。 - 筛选事件不触发:你把
(ngSubmit)="applyFilter()"绑在了mat-form-field标签上,但ngSubmit只会在原生<form>元素上触发,绑在mat-form-field上永远不会执行筛选方法,导致输入内容后没有任何逻辑运行。 - 表格结构不规范:你把
<tr mat-header-row>、<tr mat-row>外层套了<div>,Angular Material的表格是严格依赖原生table的语义结构渲染的,包裹div会打乱DOM层级,直接导致渲染异常。同时缺少displayedColumns的明确定义,这个数组需要和所有matColumnDef的名称完全对应,否则表格无法正常渲染列。 - 数据源初始化时机错误:如果你的
dataSource是从异步接口加载的,直接在类属性初始化时写dataSour = new MatTableDataSource(this.dataSource),此时传入的dataSource还是空值,后续接口返回数据后也不会同步到dataSour实例里,就算绑对了数据源也拿不到数据。
修复后的正确实现
组件TS代码
// 定义列展示顺序,值和matColumnDef的名称完全一致 displayedColumns: string[] = ['a', 'b', 'c', 'd', 'e', 'f', 'g']; filterValue: string = ''; // 先初始化空的MatTableDataSource,不要直接传入可能为空的异步数据 dataSour = new MatTableDataSource(); // 等异步数据拿到后,赋值给dataSour的data属性 ngOnInit() { // 替换成你实际的接口请求逻辑 this.你的数据请求方法().subscribe(列表数据 => { this.dataSour.data = 列表数据; }) } applyFilter (){ this.dataSour.filter = this.filterValue.trim().toLowerCase(); console.log(this.filterValue); }
组件HTML代码
<!-- 绑定输入实时触发筛选,不需要靠回车提交 --> <mat-form-field> <input name="filterValue" [(ngModel)]="filterValue" (ngModelChange)="applyFilter()" matInput placeholder="Filter" > </mat-form-field> <div class="row"> <!-- 表格的dataSource替换成带筛选能力的dataSour实例 --> <table mat-table [dataSource]="dataSour" class="mat-elevation-z8"> <!-- 原有列定义保持不变,去掉多余的*ngIf判断避免破坏结构 --> <ng-container matColumnDef="a"> <th mat-header-cell *matHeaderCellDef> Columna 1 </th> <td mat-cell *matCellDef="let dataobj"> {{dataobj.a}} </td> </ng-container> <ng-container matColumnDef="b"> <th mat-header-cell *matHeaderCellDef> Columna 2 </th> <td mat-cell *matCellDef="let dataobj"> {{dataobj.b}} </td> </ng-container> <ng-container matColumnDef="c"> <th mat-header-cell *matHeaderCellDef> Columna 3 </th> <td mat-cell *matCellDef="let dataobj"> {{dataobj.c}} </td> </ng-container> <ng-container matColumnDef="d"> <th mat-header-cell *matHeaderCellDef> Columna 4 </th> <td mat-cell *matCellDef="let dataobj"> {{dataobj.d}} </td> </ng-container> <ng-container matColumnDef="e"> <th mat-header-cell *matHeaderCellDef> Columna 5 </th> <td mat-cell *matCellDef="let dataobj"> {{dataobj.e}} </td> </ng-container> <ng-container matColumnDef="f"> <th mat-header-cell *matHeaderCellDef> Columna 6 </th> <td mat-cell *matCellDef="let dataobj"> {{dataobj.f}} </td> </ng-container> <ng-container matColumnDef="g"> <th mat-header-cell *matHeaderCellDef> Columna 7 </th> <td mat-cell *matCellDef="let dataobj"> {{dataobj.g}} </td> </ng-container> <!-- 去掉包裹tr的div,直接把行元素放在table标签下 --> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> </table> </div>
常见补充调整
- 默认筛选逻辑会遍历每一行的所有属性值做小写匹配,如果需要只筛选指定列、或者调整匹配规则,可重写
dataSour.filterPredicate方法实现自定义匹配逻辑。 - 空数据提示直接写在table标签外部判断即可,不要套在表格内部的列、行元素上,避免破坏Material表格的渲染结构。
内容的提问来源于stack exchange,提问作者arnoldo gonzalez
相关产品推荐
相关产品推荐

