在Angular Material Table上调用renderRows()

av0*_*000 21 methods angular-material viewchild angular

我正在尝试在更新表中使用的数据后刷新我的Angular Table.

文档说"你可以通过调用renderRows()方法触发对表的渲染行的更新." 但它不像普通的子组件,我可以使用"@ViewChild(MatSort)排序:MatSort;" 因为我不导入它.

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

我怎么称呼这种方法?谢谢!

我的表格代码片段:

<mat-table #table [dataSource]="dataSource" myTable class="dataTable">
Run Code Online (Sandbox Code Playgroud)

Bra*_*nce 54

确保导入ViewChild和MatTable:

import {Component, ViewChild} from '@angular/core';
import {MatTable} from '@angular/material';
Run Code Online (Sandbox Code Playgroud)

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

@ViewChild(MatTable) table: MatTable<any>;
Run Code Online (Sandbox Code Playgroud)

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

delete(row: any): void {
  /* delete logic here */
  this.table.renderRows();
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 由于 Angular 8 ViewChild 需要一个新的“静态”属性。@ViewChild(MatTable, { static: false }) 表:MatTable&lt;any&gt;; 更多信息在这里:https://angular.io/guide/static-query-migration (6认同)
  • 如果您的stackbliz预览不起作用,就像我没有在Chrome中那样,您可能会阻止第三方Cookie.这里提出了一个问题:https://github.com/stackblitz/core/issues/162以及cvietor发布的解决方法. - > chrome:// settings/content/cookies - > allow - > Add:[*.] stackblitz.io (2认同)
  • “在 Angular 版本 9 及更高版本中,可以安全地删除任何 {static: false} 标志,我们将在示意图中为您完成此清理工作。” [此处](https://angular.io/guide/static-query-migration#why-do-i-have-to-specify-static-false-isnt-that-the-default)声明。 (2认同)

Mis*_*ith 12

该表对用户不太友好,它迫使您手动更新,这错过了使用 Angular 进行绑定的要点。文档中指出:

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

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

<table #myTable mat-table ... >
Run Code Online (Sandbox Code Playgroud)

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

export class SomeComponent implements OnInit {
    @ViewChild(MatTable) myTable!: MatTable<any>;
Run Code Online (Sandbox Code Playgroud)

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

所以现在你可以这样做:

this.myTable.renderRows();   
Run Code Online (Sandbox Code Playgroud)

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


Laz*_*vić 5

@ViewChild('myTable') myTable: MatTableModule

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

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

@ViewChild(MatTable) matTable: MatTable
Run Code Online (Sandbox Code Playgroud)

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