You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 20:22:05