Angular-表排序不适用于嵌套对象

时间:2020-09-24 17:43:26

标签: javascript json angular sorting angular-material

我有一个角度表,但日期排序不正确。除日期外,其余各栏的排序都很好。我认为这是因为日期是一个嵌套对象,我尝试使用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>

} 

4 个答案:

答案 0 :(得分:1)

是的,问题是因为它是一个对象。 y[0]['0'].Date = "Sep 23"描述了要纳入排序功能的属性。因此,从这个对象开始:

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

因此,如果可能,请更改dataSource对象并仅提供所需的日期(因为您似乎在表中始终只使用date)。

您还可以覆盖CreatedTime function of a MatDatSource,它最初看起来像这样的atm:

sortingDataAccessor

您需要添加一个条件来查看当前的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'

p.s。如果要保留该功能,则需要从Angular导入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; } MAX_SAFE_INTEGER

答案 1 :(得分:0)

我可以在您的代码中检测到一些问题:

  1. 您的所有日期都相同,因此不会影响排序。
  2. 您已进入函数changeSort的if语句if(event.direction === "desc")中,尝试将其更改为if(event.active === "date"),其他排序都可以正常工作,并且您只想在日期排序中排除此条件

答案 2 :(得分:0)

看来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];
        }
    };
}

A complete stackblitz example example can be seen here

答案 3 :(得分:0)

将unix时间戳存储为数据,并在屏幕上显示时对其进行格式化。这样,您无需创建排序功能。

这是一个可行的例子 https://stackblitz.com/edit/angular-j7ycna-wdvvnw