当可观察到dataSource时,MatSort不适用于Angular Material Table

时间:2018-08-09 04:54:44

标签: angular html-table angular-material observable

我正在尝试使我的数据表之一使用默认排序功能。 我正在为此使用MatSoftModule角材料表。

现在,我已经从API加载了非常简单的数据。在我的控制器中,我正在调用一个返回Observable的服务函数:

export class DomainComponent implements OnInit {

  domains$: Observable<Domain[]>;

  columnsToDisplay = ['id', 'title'];

  constructor(private domainService: DomainService) { }

  ngOnInit() {
    this.loadDomains();
  }

  private loadDomains() {
    this.domains$ = this.domainService.getDomains();
  }

}

在视图中,我只是使用可观察的数据源:

<table mat-table [dataSource]="domains$" matSort matSortActive="id" matSortDirection="asc" class="mat-elevation-z4">

    <!-- Id Column -->
    <ng-container matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> No. </th>
      <td mat-cell *matCellDef="let element" class="td-id"> {{element.id}} </td>
    </ng-container>

    <!-- Title Column -->
    <ng-container matColumnDef="title">
      <th mat-header-cell *matHeaderCellDef mat-sort-header> Title </th>
      <td mat-cell *matCellDef="let element" class="td-title"> {{element.title}} </td>
    </ng-container>

    <tr mat-header-row *matHeaderRowDef="columnsToDisplay"></tr>
    <tr mat-row *matRowDef="let row; columns: columnsToDisplay"></tr>
  </table>

表本身可以很好地工作,在这种情况下,标题甚至显示为可排序(甚至可单击)。但是,排序实际上并没有改变。

摘自文档:https://material.angular.io/components/table/overview#sorting

看来我需要听dataSource的“ bind” sort函数到matSort上。但是,文档讨论的是对象的简单数组。

在没有某种疯狂的自定义DataSource实现的情况下使排序工作最简单的方法是什么,如此处所述:https://blog.angular-university.io/angular-material-data-table/

1 个答案:

答案 0 :(得分:1)

您可以使用map运算符对Observable数据进行排序。在ngOnInit中,您将初始排序顺序作为参数传递给loadDomains

import { map } from "rxjs/operators";
import { Sort } from "@angular/material";

ngOnInit() {
  this.loadDomains({active: "id", direction: "asc"});
}

loadDomains(sort: Sort) {
  this.domains$ = this.domainService.getDomains().pipe(
    map((domains: Array<Domain>) => domains.sort((d1, d2) => this.sortDomains(d1, d2, sort)))
  );
}

sortDomains(d1: Domain, d2: Domain, sort: Sort) {
  const one = sort.direction === "asc" ? 1 : (sort.direction === "desc" ? -1 : 0);
  if (d1[sort.active] > d2[sort.active]) {
    return one;
  } else if (d1[sort.active] < d2[sort.active]) {
    return -one;
  } else {
    return 0;
  }
}

在模板中,您可以在loadDomains事件处理程序中以新的排序顺序调用matSortChange

<table mat-table 
  class="mat-elevation-z4" 
  [dataSource]="domains$"
  matSort 
  matSortActive="id" 
  matSortDirection="asc" 
  (matSortChange)="loadDomains($event)">

基于@AlexHaslam提供的this stackblitz,您可以在original stackblitz中看到一个演示。