45

在更新表中使用的数据后,我试图让我的 Angular 表刷新。

文档说“你可以通过调用它的 renderRows() 方法来触发对表的渲染行的更新。” 但它不像普通的子组件,我可以在其中使用“@ViewChild(MatSort) sort: MatSort;” 因为我不导入它。

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

我怎么能调用这个方法?谢谢!

我的表格代码片段:

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

4 回答 4

102

确保导入 ViewChild 和 MatTable:

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

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

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

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

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

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

我自己解决此问题时发现的一些来源:

于 2018-05-23T18:41:56.147 回答
5

这个表对用户不是很友好,它会强制你手动更新,这错过了使用 Angular 进行绑定的意义。文档中指出:

由于该表针对性能进行了优化,因此它不会自动检查数据数组的更改。相反,当在数据数组上添加、删除或移动对象时,您可以通过调用其 renderRows() 方法来触发对表的渲染行的更新。

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

<table #myTable mat-table ... >

然后在您的 Typescript 文件中,声明一个与您在模板中的主题标签后放置的名称相同的公共成员,并使用它进行装饰,ViewChild以便 Angular 注入它(我不会显示导入):

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

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

所以现在你可以这样做:

this.myTable.renderRows();   

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

于 2021-06-05T23:16:14.980 回答
4

@ViewChild('myTable') myTable: MatTableModule

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

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

@ViewChild(MatTable) matTable: MatTable

装饰器中的参数ViewChild是您要查询的组件,类型只是为了您的方便——您可以省略它或说any,但如果您不这样做,您将无法从 TypeScript 获得任何帮助,因此建议您离开它。

于 2018-03-14T17:42:43.670 回答
0

您可以使用

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
  }
}
于 2021-01-29T13:04:06.803 回答