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); } } }
问题原因
- 排序初始化时机错误:
MatSort在ngAfterViewInit阶段已完成初始化,此时动态添加的列的mat-sort-header无法被MatSort识别注册。 - 冗余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
相关产品推荐
相关产品推荐

