如何以编程方式对 MatTableDataSource 进行排序?

How to sort MatTableDataSource programmatically?

我正在尝试以编程方式对 MatTableDataSource 进行排序,以便在特定移动设备中查看数据时,我可以通过使用按钮而不是 table 列 header 对数据进行排序布局。但是,我在这样做时遇到了麻烦。

我已遵循 关于如何操作的建议,但未反映数据排序。使用与 table:

相同数据的移动布局设计
<mat-card matSort *ngFor="let item of dataSource.filteredData">

我用来尝试对数据进行排序的函数是:

sortDataSource(id: string, start: string){
  this.dataSource.sort.sort(<MatSortable>({id: id, start: start}));
}

通过点击 mat-menu 中的按钮调用,例如

<mat-menu #sortMenu="matMenu" yPosition="below" [overlapTrigger]="false">
            <button mat-menu-item (click)="sortDataSource('createdDate', 'asc')"><span>Creation Date</span><mat-icon>arrow_upward</mat-icon></button>

如有任何帮助,我们将不胜感激!

Link to StackBlitz.

编辑:添加我将数据分配给来自 Observable 数组的 table 数据源的位置:

this.data$.subscribe(data => {
      this.dataSource.data = data;
      this.dataSource.paginator = this.paginator;
      this.dataSource.sort = this.sort;
}

编辑 2:删除了错误图像,通过将 "matSort" 添加到 mat-card 使用 *ngFor 来创建 mat-table 的移动布局版​​本。

更新

已向 Github.com 的 Material 团队报告了一个错误。目前看来这是不可能的。请使用手动方法或实施您自己的排序 header.


尝试手动排序数据源的数据:

sortDataSource(id: string, start: string) {
    this.dataSource.sort.sort(<MatSortable>({ id: id, start: start }));
    this.dataSource.data.sort((a: any, b: any) => {
        if (a.createdDate < b.createdDate) {
            return -1;
        } else if (a.createdDate > b.createdDate) {
            return 1;
        } else {
            return 0;
        }
    });
}

您可以使用函数的 id 和 start 参数轻松地使其更通用。

当您使用 matSort 重新分配 dataSource.sort 时,模板会收到有关更改的通知并表示更改。

component.ts

@ViewChild(MatSort, { static: false }) matSort: MatSort;

  orderData(id: string, start?: 'asc' | 'desc') {
    const matSort = this.dataSource.sort;
    const toState = 'active';
    const disableClear = false;

    matSort.sort({ id: null, start, disableClear });
    matSort.sort({ id, start, disableClear });

    this.dataSource.sort = this.matSort;
  }

component.html

<button mat-raised-button
   (click)="orderData('nameOfColumn', 'asc')">ASC</button>
<button mat-raised-button
   (click)="orderData('nameOfColumn', 'desc')">DESC</button>

可能是 Material Table

的最短手动排序函数

这是我结合JavaScript的简短解决方案:

sortDataSource(idVal: string, startVal?: string): void {
    this.dataSource.data.sort(
        (a, b) => {
            return startVal === 'asc' ? a[idVal] - b[idVal] : (startVal === 'desc' ? b[idVal] - a[idVal] : a[idVal] - b[idVal]);
        }
    );
}

https://stackblitz.com/edit/angular-mat-sort-default-ytu6ch

看看这个!

而不是使用 array.sort 手动排序 我们可以利用 @ViewChild(MatSort) 排序!:MatSort; 和 从'@angular/material/sort';

导入{MatSort, Sort}

根据条件排序。