Angular Material:循环内mat-table排序失效问题求助
问题排查与解决
核心问题分析
- 多表格MatSort实例获取错误:使用
@ViewChild(MatSort)只能拿到DOM中第一个matSort实例,循环生成的其他表格的Sort实例未绑定到对应数据源,导致排序失效。 - 仅初始化第一个数据源的排序配置:代码仅给
this.datasource[0]设置了sortingDataAccessor和sort,其余数据源未配置排序逻辑。 - 生命周期时机错误:
ngOnInit中DOM未完全渲染,此时this.sort可能未初始化,绑定操作无效。 - sortingDataAccessor遗漏字段:
displayedColumns包含rateChangeType,但排序数据访问器未处理该字段,点击该列排序时会走默认逻辑,无有效排序依据。
修复步骤
1. 修改MatSort实例获取方式
改用@ViewChildren获取所有表格的Sort实例:
import { ViewChildren, QueryList } from '@angular/core'; import { MatSort } from '@angular/material/sort'; // 组件类内定义 @ViewChildren(MatSort) sorts!: QueryList<MatSort>;
2. 调整生命周期钩子到ngAfterViewInit
DOM渲染完成后再绑定Sort实例并配置排序:
ngAfterViewInit() { this.datasource.forEach((dataSource, index) => { // 绑定对应表格的Sort实例 dataSource.sort = this.sorts.toArray()[index]; // 统一配置排序数据访问器 dataSource.sortingDataAccessor = (item: any, property) => { return item.list[property] ?? item[property]; }; }); }
3. 简化数据源初始化逻辑
保留ngOnInit中的数据源初始化,移除单独给第一个数据源配置排序的代码:
ngOnInit(){ this.filteredSizeCode.forEach((size: any) => { let data: any[] = size.list.map((x: any) => ({ ...size, list: x })); this.datasource.push(new MatTableDataSource(data)); }); }
4. 确认HTML配置正确性
循环中的每个表格已添加matSort,mat-sort-header字段名与matColumnDef匹配,无需修改。
完整修复后的TS代码示例
import { Component, OnInit, AfterViewInit, ViewChildren, QueryList } from '@angular/core'; import { MatTableDataSource } from '@angular/material/table'; import { MatSort } from '@angular/material/sort'; @Component({ // 组件元数据(如selector、templateUrl等) }) export class YourComponent implements OnInit, AfterViewInit { displayedColumns = [ 'unitRateType', 'rateChangeType', 'effectiveDate' ]; @ViewChildren(MatSort) sorts!: QueryList<MatSort>; datasource: MatTableDataSource<any>[] = []; filteredSizeCode: any[] = []; // 假设该变量已被正确赋值 ngOnInit(){ this.filteredSizeCode.forEach((size: any) => { let data: any[] = size.list.map((x: any) => ({ ...size, list: x })); this.datasource.push(new MatTableDataSource(data)); }); } ngAfterViewInit() { this.datasource.forEach((dataSource, index) => { dataSource.sort = this.sorts.toArray()[index]; dataSource.sortingDataAccessor = (item: any, property) => { return item.list[property] ?? item[property]; }; }); } }
内容的提问来源于stack exchange,提问作者Asna Khan
相关产品推荐
相关产品推荐

