Angular Material数据表无数据时隐藏表头且matSort正常生效问题
问题根因
[hidden]失效是因为Angular Materialmat-table的默认CSS优先级高于[hidden]自带的display: none规则,导致隐藏属性被覆盖。- 外层用
*ngIf包裹表格导致matSort失效是因为*ngIf会在无数据时直接移除表格DOM,挂载在表格上的matSort指令实例也会被销毁,后续数据加载重新渲染表格后,@ViewChild查询到的matSort实例没有重新绑定到数据源,所以排序失效。
可行解决方案
方案1:单独控制表头行显示(最推荐)
不操作整个表格的DOM,只控制表头行的渲染,表格始终保留在DOM中,matSort指令不会被销毁,功能完全不受影响。
注意Angular不支持同一元素同时使用多个结构型指令,所以需要用<ng-container>包裹表头行:
<table mat-table [dataSource]="data" matSort> <ng-container matColumnDef="productName"> <th mat-header-cell *matHeaderCellDef mat-sort-header> Product Name </th> <td mat-cell *matCellDef="let row"> {{row.productName}} </td> </ng-container> ... <!-- 仅当有数据时渲染表头行 --> <ng-container *ngIf="data?.length"> <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> </ng-container> <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr> </table>
方案2:修复*ngIf包裹后的排序绑定
如果你确实需要用*ngIf控制整个表格的显示/隐藏,只需要在数据加载完成后手动重新绑定matSort实例到数据源即可:
组件类代码:
import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; export class ProductTableComponent { @ViewChild(MatSort, { static: false }) sort!: MatSort; data: any[] | undefined; dataSource = new MatTableDataSource<any>([]); displayedColumns = ['productName', /* 其他列名 */]; // 你的数据加载逻辑 loadProductData() { this.productService.getProducts().subscribe(res => { this.data = res; this.dataSource.data = res; // 等待DOM更新完成后绑定排序实例 setTimeout(() => { this.dataSource.sort = this.sort; }, 0); }) } }
方案3:修复[hidden]的样式优先级
给mat-table添加自定义样式强制[hidden]属性生效,表格仅隐藏不销毁,matSort功能不受影响:
首先在全局样式或者组件样式中添加规则:
/* 覆盖mat-table默认样式,让hidden属性生效 */ mat-table[hidden], table[mat-table][hidden] { display: none !important; }
你的原有HTML代码不需要修改,[hidden]="!data"即可正常生效。
内容的提问来源于stack exchange,提问作者Swaroop R M
相关产品推荐
相关产品推荐

