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

Angular父子组件传递表格列的matSort排序异常问题

Angular 子组件传入列排序失效问题

我尝试在Angular中将表格列从父组件传递到子组件,但遇到了该列的排序问题。其他列排序正常,仅父组件传入的"another"列排序功能失效。

父组件代码

<table-sorting-example matSort>
  <ng-container matColumnDef="another">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Another</th>
    <td mat-cell *matCellDef="let element">{{element.another}}</td>
  </ng-container>
</table-sorting-example>

子组件模板代码

<table mat-table [dataSource]="dataSource" matSort>
  <ng-container matColumnDef="position">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Position</th>
    <td mat-cell *matCellDef="let element">{{element.position}}</td>
  </ng-container>

  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Name</th>
    <td mat-cell *matCellDef="let element">{{element.name}}</td>
  </ng-container>

  <ng-container matColumnDef="weight">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Weight</th>
    <td mat-cell *matCellDef="let element">{{element.weight}}</td>
  </ng-container>

  <ng-container matColumnDef="symbol">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Symbol</th>
    <td mat-cell *matCellDef="let element">{{element.symbol}}</td>
  </ng-container>

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

子组件TS代码

import {
  AfterViewInit,
  Component,
  ContentChildren,
  QueryList,
  ViewChild,
} from '@angular/core';
import { MatSort, Sort } from '@angular/material/sort';
import {
  MatColumnDef,
  MatTable,
  MatTableDataSource,
} from '@angular/material/table';

export interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  symbol: string;
  another: string;
}
const ELEMENT_DATA: PeriodicElement[] = [
  { position: 5, name: 'Boron', weight: 10.811, symbol: 'B', another: 'A' },
  { position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C', another: 'B' },
  { position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N', another: 'C' },
  { position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O', another: 'D' },
  { position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F', another: 'E' },
  { position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne', another: 'F' },
];

@Component({
  selector: 'table-sorting-example',
  styleUrls: ['table-sorting-example.css'],
  templateUrl: 'table-sorting-example.html',
})
export class TableSortingExample implements AfterViewInit {
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
  dataSource = new MatTableDataSource(ELEMENT_DATA);

  @ViewChild(MatTable) myTable: MatTable<PeriodicElement>;
  @ViewChild(MatSort) sort: MatSort;
  @ContentChildren(MatColumnDef) private customCols: QueryList<MatColumnDef>;

  ngAfterViewInit() {
    this.dataSource.sort = this.sort;
    for (let col of this.customCols) {
      this.myTable.addColumnDef(col);
      this.displayedColumns.push(col.name);
    }
  }
}

问题原因

  1. 排序初始化时机错误:MatSort在ngAfterViewInit阶段已完成初始化,此时动态添加的列的mat-sort-header无法被MatSort识别注册。
  2. 冗余matSort干扰:父组件的<table-sorting-example>标签上添加的matSort是多余的,会干扰子组件内部MatSort的正常工作。

修复方案

步骤1:移除父组件冗余matSort属性

修改父组件代码,去掉多余的matSort:

<table-sorting-example>
  <ng-container matColumnDef="another">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>Another</th>
    <td mat-cell *matCellDef="let element">{{element.another}}</td>
  </ng-container>
</table-sorting-example>

步骤2:调整列添加与排序初始化顺序

修改子组件的ngAfterViewInit方法,先添加自定义列,再设置数据源排序,确保新列的排序头被正确识别:

ngAfterViewInit() {
  // 先添加所有自定义列定义
  this.customCols.forEach(col => {
    this.myTable.addColumnDef(col);
    this.displayedColumns.push(col.name);
  });
  // 再绑定排序,确保新列的sort-header已完成注册
  this.dataSource.sort = this.sort;
}

可选:自定义排序数据访问器

若仍存在数据识别问题,可为数据源添加自定义排序数据访问器,确保动态列数据能被正确读取:

ngOnInit() {
  this.dataSource.sortingDataAccessor = (item, property) => {
    // 兼容动态列的数据读取
    return item[property] ?? '';
  };
}

内容的提问来源于stack exchange,提问作者ajaycod

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 07:24:57