角度材料数据表-无法排序

时间:2020-06-03 20:46:52

标签: angular datatable angular-material

试图对我的数据进行排序,由于某种原因,它无法正常工作。所有示例都使用本地值数组,而我的示例是一个API调用,它返回一个对象数组,其中每个项目都有一个“名称”属性。

我可以加载页面并看到排序标题箭头,但是单击不会产生变化。我正在使用一个函数调用来获取我的“客户端”,并在构造函数中调用它,但是对于我来说,在OnInit中都失败了。我还检查了我的列def是否与返回的数据字段相同,即“名称”,但这也无济于事。

------ TS ---------

import { Component, OnInit, ViewChild } from "@angular/core";
import { Router } from "@angular/router";

import { ClientService } from "../../../core/services/client.service";
import { Client } from "../../../core/models/client.interface";
import { MatDialog, MatDialogConfig } from "@angular/material/dialog";
import { ClientDialogComponent } from "../client-dialog/client-dialog.component";
import { ConfirmDeleteDialogComponent } from "../../../core/components/confirm-delete-dialog/confirm-delete-dialog.component";
import { SnackbarService } from "src/app/core/services/snackbar.service";
import { MatTableDataSource } from "@angular/material/table";
import { MatSort } from "@angular/material/sort";

@Component({
  templateUrl: "./clients.component.html",
  styleUrls: ["./clients.component.css"],
})
export class ClientsComponent implements OnInit {
  dataSource: MatTableDataSource<Client[]>;
  client: Client;
  tableColumns: string[] = ["name", "website", "phone", "actions"];

  @ViewChild(MatSort) sort: MatSort;

  constructor(
    private _clientService: ClientService,
    private _router: Router,
    private _snackbar: SnackbarService,
    public dialog: MatDialog
  ) {
    this.getClients();
  }

  ngOnInit() {
    this.dataSource.sort = this.sort;
  }

  getClients() {
    // Get clients from API
    this._clientService.getClients().subscribe(
      (response) => {
        this.dataSource = new MatTableDataSource(response);   <----- this is simple array of objects
      },
      (error) => {
        this._snackbar.show(error["message"], "warn-snackbar");
      }
    );
  }
}

-------- HTML --------------

<div *ngIf="dataSource; else spinner">
  <div class="row">
    <div class="search">
      <mat-form-field>
        <input type="text" matInput placeholder="Filter" (keyup)="applyFilter($event.target.value)">
      </mat-form-field>
    </div>
    <div class="col-button">
      <button *hasClaim="'canAddClient'" type="button" mat-stroked-button color="primary" class="add-client-button"
        (click)="addClientDialog()">
        Add Client
      </button>
    </div>
  </div>
  <div class="row">
    <div class="col-table">
      <table mat-table [dataSource]="dataSource" matSort>
        <!-- row / column definitions -->
        <tr mat-header-row *matHeaderRowDef="tableColumns" [ngClass]="'table-header'"></tr>
        <tr mat-row *matRowDef="let row; columns: tableColumns">
        </tr>
        <!-- client -->
        <ng-container matColumnDef="name">
          <th mat-header-cell *matHeaderCellDef mat-sort-header>Client</th>
          <td mat-cell *matCellDef="let client"> {{client.name}} </td>
        </ng-container>
        <!-- website -->
        <ng-container matColumnDef="website">
          <th mat-header-cell *matHeaderCellDef>Website</th>
          <td mat-cell *matCellDef="let client"> {{client.website}} </td>
        </ng-container>
        <!-- phone -->
        <ng-container matColumnDef="phone">
          <th mat-header-cell *matHeaderCellDef>Phone</th>
          <td mat-cell *matCellDef="let client"> {{client.phone | formatPhone}} </td>
        </ng-container>
        <!-- actions -->
        <ng-container matColumnDef="actions">
          <th mat-header-cell *matHeaderCellDef>Actions</th>
          <td mat-cell *matCellDef="let client">
            <button mat-stroked-button class="action-button" color="primary" (click)="goToDetailsPage(client._id)">
              Info
            </button>
            <button *hasClaim="'canEditClient'" mat-stroked-button class="action-button" color="primary"
              (click)="editClientDialog(client)">
              Edit
            </button>
            <button *hasClaim="'canDeleteClient'" mat-stroked-button class="action-button" color="warn"
              (click)="deleteClientDialog(client)">
              Delete
            </button>
          </td>
        </ng-container>
      </table>
    </div>
  </div>
</div>

<ng-template #spinner>
  <mat-spinner></mat-spinner>
</ng-template>

2 个答案:

答案 0 :(得分:1)

我认为您的问题正在发生,因为您是在定义dataSource之前在ViewChild上设置排序的。有两种方法可以解决此问题:

  1. {static: true}添加到您的@ViewChild定义中,如下所示:

    @ViewChild(MatSort, {static: true}) sort: MatSort;
    

    这会导致Angular急切地获取MatSort元素,因此它在ngOnInit中可用。

  2. 将排序分配移至ngAfterViewInit。在您提供的代码中,您可以将ngOnInit函数重命名为ngAfterViewInit。之所以可行,是因为ViewChild中提供了非静态ngAfterViewInit对象。

如果您有兴趣,可以阅读difference between ngOnInit and ngAfterViewInitViewChildstatic标志。

答案 1 :(得分:0)

为什么不从CLI创建表?默认情况下,它包含许多功能,并且还节省了大量时间。

您可以点击您的API并存储数据,过程非常简单。对于您当前的表格,我不知道为什么它不能正常工作