如何进行默认的多重排序?

时间:2018-12-24 10:34:48

标签: sorting angular-material

这是我当前的代码:

displayedColumns: string[] = ['id', 'dataYear', 'dataMonth', 'population', 'sources', 'created_at', 'updated_at', 'actions'];

@ViewChild(MatSort) sort: MatSort;

ngOnInit() {

   this.sort.sort(<MatSortable>({id: 'updated_at', start: 'desc'}));
   this.listData.sort = this.sort;
}

我只能对一列进行默认排序。 如果我想对三列(dataYear,dataMonth,updated_at)进行排序怎么办?

下面的内容是HTML组件:

<mat-table [dataSource]="listData" matSort>
<ng-container matColumnDef="id">
<mat-header-cell *matHeaderCellDef mat-sort-header class="hide"> Id. </mat-header-cell>
<mat-cell *matCellDef="let element" class="hide"> {{element.id}} </mat-cell>
</ng-container>
<ng-container matColumnDef="dataYear">
<mat-header-cell *matHeaderCellDef mat-sort-header> Year </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.dataYear}} </mat-cell>
</ng-container>
<ng-container matColumnDef="dataMonth">
<mat-header-cell *matHeaderCellDef mat-sort-header> Month </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.dataMonth}} </mat-cell>
</ng-container>
<ng-container matColumnDef="population">
<mat-header-cell *matHeaderCellDef mat-sort-header> Population </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.population}} </mat-cell>
</ng-container>
<ng-container matColumnDef="sources">
<mat-header-cell *matHeaderCellDef mat-sort-header> Sources </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.sources}} </mat-cell>
</ng-container>
<ng-container matColumnDef="created_at">
<mat-header-cell *matHeaderCellDef mat-sort-header> Created Time </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.created_at}} </mat-cell>
</ng-container>
<ng-container matColumnDef="updated_at">
<mat-header-cell *matHeaderCellDef mat-sort-header> Updated Time </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.updated_at}} </mat-cell>
</ng-container>
<ng-container matColumnDef="actions">
<mat-header-cell *matHeaderCellDef></mat-header-cell>
<mat-cell *matCellDef="let row">
<button mat-icon-button (click)="onEdit(row)"><mat-icon>launch</mat-icon></button>
<button mat-icon-button color="warn" (click)="onDelete(row.id)"><mat-icon>delete_outline</mat-icon></button>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>

3 个答案:

答案 0 :(得分:1)

一种间接的方法是使用 sortDataAccessor 函数。

在您的函数中,您可以简单地连接主要排序列,然后它就会正确排序。

例如我想对截止日期进行排序,然后按名称对相同的日期进行排序。这是我如何实现的:

this.dataSource.sortingDataAccessor = (item, property) => {
      switch (property) {
        case 'dueDate': return (item?.dueDate + item?.name);
        case 'name': return item?.name;
}

答案 1 :(得分:0)

我认为尚不支持,请参见Github问题here

但是您可以自己对数据进行排序,而不是依靠Material数据源为您完成数据,到目前为止,它还是无法实现(即多字段排序)。

在这里,我快速stackblitz齐聚一堂。

它根本不使用matSort,而只是通过Sort对象的数组对数据源本身的数据进行排序:

export interface Sort {
  id: string;
  direction: 'asc' | 'desc';
}

multiSort: Sort[] = [
  { id: 'position', direction: 'desc' },
  { id: 'weight', direction: 'asc' },
  { id: 'name', direction: 'asc' }
];

然后使用消耗排序配置的函数:

public sort() {
  if (!this.multiSort) {
    return;
  }

  let sortedData: PeriodicElement[];
  this.multiSort.forEach(sort => {
    sortedData = this.dataSource.data
    .sort((a, b) => {
      if (sort.direction === 'asc') {
        return a[sort.id] > b[sort.id] ? 1 : -1;
      } else if (sort.direction === 'desc') {
        return a[sort.id] > b[sort.id] ? -1: 1;
      } else {
        return 0;
      }
    });
  });
  this.dataSource.data = sortedData;
}

这可能并不理想,但是根据您的要求,类似的解决方案可能会帮助您解决此问题。

答案 2 :(得分:0)

使用单一排序四次,它就会出来我想要的

优先级:update_at> dataYear>人口> created_at

this.sort.sort(<MatSortable>({id: 'created_at', start: 'desc'}));
this.sort.sort(<MatSortable>({id: 'population', start: 'desc'}));
this.sort.sort(<MatSortable>({id: 'dataYear', start: 'desc'}));
this.sort.sort(<MatSortable>({id: 'updated_at', start: 'desc'}));