在 Angular Material Table 上调用 renderRows()

Calling renderRows() on Angular Material Table

我正在尝试让 Angular Table 在更新 table 中使用的数据后进行刷新。

文档说 "you can trigger an update to the table's rendered rows by calling its renderRows() method." 但它不像一个普通的子组件,我可以在其中使用“@ViewChild(MatSort) sort: MatSort;”因为我不导入它。

如果我导入它并尝试类似@ViewChild('myTable') myTable: MatTableModule;然后我收到一条错误消息,指出 renderRows() 在该类型上不存在。

如何调用这个方法?谢谢!

我的 table 代码片段:

<mat-table #table [dataSource]="dataSource" myTable class="dataTable">

@ViewChild('myTable') myTable: MatTableModule

您不应该查询字符串。这将查询引用(定义为 <cmp #ref>)。类型也是错误的:您不是从视图中抓取模块,而是抓取组件。

您应该导入要查询的组件并执行以下操作(根据您需要查询的组件进行更改):

@ViewChild(MatTable) matTable: MatTable

ViewChild装饰器中的参数是你要查询的组件,类型只是为了你方便——你可以省略它或说any,但你不会有如果您不这样做,TypeScript 会提供任何帮助,因此建议保留它。

确保导入 ViewChild 和 MatTable:

import {Component, ViewChild} from '@angular/core';
import {MatTable} from '@angular/material';

然后您可以使用 ViewChild 获取对 table 的引用(注意 MatTable 上需要类型 T - 我只是使用了任何类型,但是如果您有类型化的 table,您将需要使用该类型:

@ViewChild(MatTable) table: MatTable<any>;

然后当您以任何方式修改 table 时,您将需要调用 renderRows() 方法。

delete(row: any): void {
  /* delete logic here */
  this.table.renderRows();
}

这是一个非常简单的工作示例: https://stackblitz.com/edit/angular-bxrahf

我自己解决这个问题时发现的一些资源:

您可以使用

import {Component, ViewChild} from '@angular/core';
import {MatTable} from '@angular/material';

@ViewChild(MatTable) table: MatTable<any>;

anyFunction(): void {
   this.table.renderRows();
}

正如在其他人的回答中提到的那样。 或者您可以将服务传递给应用程序状态(@ngrx/store) 例如:

import { Component, OnInit } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { Store } from '@ngrx/store';

import * as reducer from '../../app.reducer';

export class Test implements OnInit {
dataSource = new MatTableDataSource<any>();

constructor(private _store: Store<reducer.State>){}

 ngOnInit(): void {
    this._store.select(reducer.getYourSelectorCreated)
      .subscribe(res) => { <<<<--- Subscribe to listen changes on your "table data -state"
        this.dataSource.data = res;  <<-- Set New values to table
      });
    this._someService.fetchYourDataFromStateFunction();  <<-- Service to change the state
  }
}

这个 table 对用户来说不是很友好,它会强制您手动更新,这忽略了使用 Angular 进行绑定的要点。在 documentation 中声明:

Since the table optimizes for performance, it will not automatically check for changes to the data array. Instead, when objects are added, removed, or moved on the data array, you can trigger an update to the table's rendered rows by calling its renderRows() method.

要从 Typescrypt 代码调用 material table 组件上的方法,您需要通过对 table 的 ViewChild 引用来完成。首先在模板中的 table 添加一个带标签的名称:

<table #myTable mat-table ... >

然后在您的 Typescript 文件中,声明一个 public 成员,其名称与您在模板中的主题标签后所用的名称相同,并使用 ViewChild 对其进行修饰,以便 Angular 将其注入(我不会展示进口商品):

export class SomeComponent implements OnInit {
    @ViewChild(MatTable) myTable!: MatTable<any>;

(Angular 的新版本需要“!”来欺骗 Typescript 相信它总是非空的。事实证明它会。继续阅读)

所以现在你可以这样做:

this.myTable.renderRows();   

它会工作 除非 table 或任何父项在 *ngIf 指令中。当该指令起作用时,table 不存在于 DOM 中,并且用 ViewChild 注释的成员将是未定义的,因此您不能对其调用任何内容。这不是 material table 的问题,而是 Angular 的设计方式。检查 以获取解决方案。我最喜欢的是用 [hidden] 替换 *ngIf。如果指令在 table 中,那没问题,但当它在父级中时会变得混乱。