[英]Angular - table sorting not working for nested objects
我有一个角度表,但日期排序不正确。 除了日期之外,其余列的排序非常好。 我认为这是因为日期是一个嵌套对象,我尝试使用 matSortChange() 但没有任何效果。
我在这里创建了一个演示: DEMO
const ELEMENT_DATA: PeriodicElement[] = [
{position: 1,
name: 'A',
weight: 1.5079,
timeModel: {CreatedTime: "2020-04-30T15:38:11.186Z", LastModified: "2020-06-08T15:38:11.186Z"}
},
{position: 2,
name: 'B',
weight: 1.4079,
timeModel: {CreatedTime: "2021-03-30T15:38:11.186Z", LastModified: "2020-06-10T15:38:11.186Z"}
},
{position: 3,
name: 'C',
weight: 1.3079,
timeModel: {CreatedTime: "2020-01-30T15:38:11.186Z", LastModified: "2020-03-30T15:38:11.186Z"}
},
];
我确实尝试添加一个自定义排序函数来尝试对日期进行排序,但它无法正常工作。
public changeSort(event: Event) {
if (event.active === 'date') {
this.dataSource.filteredData = this.dataSource.filteredData.sort(function(a, b) {
return new Date(a.timeModel.CreatedTime).getTime() - new Date(b.timeModel.CreatedTime).getTime();
});
}
}
HTML
<table mat-table [dataSource]="dataSource" (matSortChange)="changeSort($event)" matSort class="mat-elevation-z8">
<!-- Position Column -->
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef mat-sort-header> No. </th>
<td mat-cell *matCellDef="let element"> {{element.position}} </td>
</ng-container>
<!-- Name Column -->
<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>
<!-- Weight Column -->
<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>
<!-- Symbol Column -->
<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Date </th>
<td mat-cell *matCellDef="let element"> {{element.timeModel.CreatedTime}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
}
是的,问题是因为它是一个对象。 matColumnDef="weight"
描述了要纳入排序功能的属性。 所以从这个对象:
{
position: 1,
name: 'A',
weight: 1.5079,
timeModel: {CreatedTime: "2020-04-30T15:38:11.186Z", LastModified: "2020-06-08T15:38:11.186Z"}
}
weight
被采取。 但是matColumnDef="date"
结果只是undefined
- 您的对象中没有属性date
。
因此,如果可能,请更改 dataSource 对象并仅提供它需要的日期(因为您似乎只在表中使用CreatedTime
)。
您还可以覆盖sortingDataAccessor
函数,它最初看起来像这样的 atm:
sortingDataAccessor: ((data: T, sortHeaderId: string) => string|number) =
(data: T, sortHeaderId: string): string|number => {
const value = (data as {[key: string]: any})[sortHeaderId];
if (_isNumberValue(value)) {
const numberValue = Number(value);
return numberValue < MAX_SAFE_INTEGER ? numberValue : value;
}
return value;
}
您需要添加一个条件来查看当前的sortHeaderId
值是否为'date'
。 然后告诉它如何获取要在排序函数中使用的对象所需的值:
this.dataSource.sortingDataAccessor = (data, sortHeaderId) => {
const value = (data as {[key: string]: any})[sortHeaderId];
const MAX_SAFE_INTEGER = 9007199254740991;
if (_isNumberValue(value)) {
const numberValue = Number(value);
return numberValue < MAX_SAFE_INTEGER ? numberValue : value;
}
if (sortHeaderId === 'date') {
return new Date(data.timeModel.CreatedTime)
}
return value;
}
ps 如果想保留该功能,您需要从 Angular 导入MAX_SAFE_INTEGER
和_isNumberValue
。
我可以在您的代码中检测到一些问题:
changeSort
一个 if 语句if(event.direction === "desc")
,尝试将其更改为if(event.active === "date")
,其他排序工作正常,你想要排除此条件仅对日期排序。看起来 Angular 不知道应该排序的属性的正确方法。 因此,我们可以使用自定义排序数据访问器将其显示给 Angular:
public changeSort(event: Event) {
console.log(event)
this.dataSource.sortingDataAccessor = (item, property) => {
switch (property) {
case 'date': return item.timeModel.CreatedTime;
default: return item[property];
}
};
}
将 unix 时间戳存储为数据并在屏幕上显示时对其进行格式化。 这样您就不需要创建排序函数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.