使用Material表格和REST API删除记录后,如何刷新Angular表格?

3

我有一个带有可展开行的材料表格(https://material.angular.io/components/table/examples),我想要在表格中管理删除,因此我创建了一个带有触发删除事件功能的删除按钮。API正常工作,记录已正确删除,但是在删除后表格没有刷新,我希望实现这种行为。这里有一个使用虚假API的stackblitz:https://stackblitz.com/edit/angular-comzph

我尝试在我的删除函数中调用ngOnInt并返回到相同的路由,但什么也没发生...

deleteCustomer(id) {
 this.api.deleteCustomer(id)
  .subscribe(res => {
    alert(`cliente rimosso`);
    // TODO fix reload list after delete
    // this.router.navigate['/clienti'];
    this.ngOnInit();
  }, (err) => {
    console.log(err);
  }
 );
}

我尝试使用这个解决方案,但它并没有起作用。我也尝试使用ngOnChanges和ngOnDestroy,但它们也没有起作用...

有人能帮帮我吗?


不需要完全刷新或重新初始化组件,你可以通过调用API重新获取数据来刷新表格数据集。 - Gijs Post
我也尝试在 deleteCustomer() 方法中调用 this.api.getCustomers(),但是没有起作用。 - ufollettu
也许可以使用管道? this.api.deleteCustomer(id).pipe(flatMap(_ => this.api.getCustomers)).subscribe(result => { // 将结果分配给 data 变量 }) - Gijs Post
不行,不起作用。可能是传递给 mat-table HTML 的 datasource 属性存在问题。 - ufollettu
我使用以下解决方案解决了这个问题:https://dev59.com/6lYN5IYBdhLWcg3w4bn1,感谢您的帮助。 - ufollettu
3个回答

5
不需要为获取更新的数据再次调用服务器并下载所有数据。只需调用下面的函数并在dataSource中删除行(splice)。从您的删除函数传递记录id和包含id的列名,神奇的事情就会发生。我包括paginator。
我的Angular Material Table StackBlitz有一个可工作的示例。还请参阅我使用于CREATE AND UPDATE的UpdateDatatableService
// Remove the deleted row from the data table. 
// Need to remove from the downloaded data first.

  private deleteRowDataTable (recordId, idColumn, paginator, dataSource) {
    this.dsData = dataSource.data;
    const itemIndex = this.dsData.findIndex(obj => obj[idColumn] === recordId);
    dataSource.data.splice(itemIndex, 1);
    dataSource.paginator = paginator;
  }

splice调用返回不包含该行的数据,如果直接对MatTableDataSource进行拼接,请使用-this.myDataSource = this.myDataSource.data.splice(index, 1); - Airo

3
Angular 的文档显示了一个方法 renderRows(),它适用于 元素。我遇到了同样的问题,实现了这个方法,它很好用。我也学到了你可以选择提供数据流而不是简单的数据。下面解决了使用简单数据渲染行的问题。
在 HTML 模板中,给 元素加上一个属性绑定:
<table mat-table [dataSource]="data" #myTable> <!-- #table binding here -->
  <!-- table cells content etc... -->
</table>


import { MatTable } from '@angular/material/table';

export class MyComponent {
    @ViewChild('myTable') myTable: MatTable<any>; /*not exatly sure what the type should be set too */

    editDataMethod(){
        /* data handling logic */
        this.myTable.renderRows();

}
在组件类中使用 @ViewChild 链接到模板属性,并在表格数据更改时调用 renderRows() 方法。

0

我解决了每次刷新客户列表时创建新的 mat-table 数据源的问题。我需要在构造函数中提供 ChangeDetectorRef,然后编写以下代码:

refreshCustomersList() {
 this.api.getCustomers()
  .subscribe(res => {
    console.log(res);
    this.clienti = res;
    this.dataSource = new ClientiDataSource(this.api);
    this.changeDetectorRefs.detectChanges();
  }, err => {
    console.log(err);
 });
}

它有效!

NB:只有在使用 mat-table 数据源时才会出现此问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接