Angular BehaviorSubject 在 mat 排序后未更新 mat table UI
Angular BehaviorSubject not updating mat table UI after mat sort
我有一个 mat-table 想要添加排序。我将 MatSort
和 mat-sort-header
标签添加到我的 table/headers,并将 (MatSortChange)
事件添加到 table。我有一个行为主题作为我的数据源,在 ngOnInit
中我从后端获取初始数据。从那里,如果用户想要排序,他们单击排序 header,它会调用更改事件,该事件会调用我的自定义函数来对我的数据进行排序。在我的排序函数结束时,我调用 behaviorSubject.next(sortedData)
并且我的 table UI 没有更新。我已经检查了 .next()
调用之前的值,它是正确的。我还记录了 behaviorSubject.value
,它也显示了正确的数据,但是 table UI 没有更新。
Table HTML
<div *ngIf="(this.dataSource$ | async) as dataSource">
<table mat-table [dataSource]="dataSource" matSort (matSortChange)="sortData($event)">
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> ID</th>
<td mat-cell *matCellDef="let item"> {{item.id}} </td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
<td mat-cell *matCellDef="let item"> {{item.name}} </td>
</ng-container>
<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>
<td mat-cell *matCellDef="let item"> {{item.date | date: 'MM/dd/yyyy'}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
component.ts
dataSource$: BehaviorSubject<Person[]> = new BehaviorSubject([]);
...
ngOnInit(): void {
this.service.getData().subscribe((val) => this.dataSource$.next(val));
sortData(event: MatSort) {
const columnToSort = event.active;
const direction = event.direction === 'asc' ? 1 : -1;
const data = this.dataSource$.value;
data.sort((a, b) => {
if(a[columnToSort] < b[columnToSort]) {
return -1 * direction;
} else {
return 1 * direction;
}
});
this.dataSource$.next(data);
}
您的参考永远不会改变,垫子 table 需要知道重新渲染。您可以使用传播运算符复制您的数据:
sortData(event: MatSort) {
//...
this.dataSource$.next([...data]);
}
我有一个 mat-table 想要添加排序。我将 MatSort
和 mat-sort-header
标签添加到我的 table/headers,并将 (MatSortChange)
事件添加到 table。我有一个行为主题作为我的数据源,在 ngOnInit
中我从后端获取初始数据。从那里,如果用户想要排序,他们单击排序 header,它会调用更改事件,该事件会调用我的自定义函数来对我的数据进行排序。在我的排序函数结束时,我调用 behaviorSubject.next(sortedData)
并且我的 table UI 没有更新。我已经检查了 .next()
调用之前的值,它是正确的。我还记录了 behaviorSubject.value
,它也显示了正确的数据,但是 table UI 没有更新。
Table HTML
<div *ngIf="(this.dataSource$ | async) as dataSource">
<table mat-table [dataSource]="dataSource" matSort (matSortChange)="sortData($event)">
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> ID</th>
<td mat-cell *matCellDef="let item"> {{item.id}} </td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Name </th>
<td mat-cell *matCellDef="let item"> {{item.name}} </td>
</ng-container>
<ng-container matColumnDef="date">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>
<td mat-cell *matCellDef="let item"> {{item.date | date: 'MM/dd/yyyy'}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
component.ts
dataSource$: BehaviorSubject<Person[]> = new BehaviorSubject([]);
...
ngOnInit(): void {
this.service.getData().subscribe((val) => this.dataSource$.next(val));
sortData(event: MatSort) {
const columnToSort = event.active;
const direction = event.direction === 'asc' ? 1 : -1;
const data = this.dataSource$.value;
data.sort((a, b) => {
if(a[columnToSort] < b[columnToSort]) {
return -1 * direction;
} else {
return 1 * direction;
}
});
this.dataSource$.next(data);
}
您的参考永远不会改变,垫子 table 需要知道重新渲染。您可以使用传播运算符复制您的数据:
sortData(event: MatSort) {
//...
this.dataSource$.next([...data]);
}