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



尝试对我的数据进行排序,但由于某种原因它不起作用。所有示例都使用本地值数组,而我的示例是一个 API 调用,它返回一个对象数组,其中每个项目都有一个"name"属性。

我可以加载页面并看到排序标题箭头,但单击不会产生更改。我正在使用函数调用来获取我的"客户端"并在构造函数中调用它,但在两个 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>

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

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

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

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

  2. 将排序分配移到ngAfterViewInit中。 在您提供的代码中,您可以将ngOnInit函数重命名为ngAfterViewInit。 这是有效的,因为非静态ViewChild对象在ngAfterViewInit中可用。

如果您有兴趣,可以阅读ngOnInitngAfterViewInit之间的区别以及要ViewChildstatic标志。

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

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

最新更新