【问题标题】:Calling renderRows() on Angular Material Table在 Angular 材质表上调用 renderRows()
【发布时间】:2018-08-23 08:57:14
【问题描述】:

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

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

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

如何调用此方法?谢谢!

我的表码sn-p:

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

【问题讨论】:

  • 不导入,怎么用?

标签: angular methods angular-material viewchild


【解决方案1】:

确保导入 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

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

【讨论】:

  • 如果你的 stackbliz 预览不能像我在 chrome 中那样工作,你可能阻止了 3rd 方 cookie。已在此处提交了一个问题:github.com/stackblitz/core/issues/162 以及 cvietor 发布的解决方法。 -> chrome://settings/content/cookies -> 允许 -> 添加:[*.]stackblitz.io
  • 像魅力一样工作。!!
  • 由于 Angular 8 ViewChild 需要一个新的“静态”属性。 @ViewChild(MatTable, { static: false }) 表:MatTable;更多信息在这里:angular.io/guide/static-query-migration
  • 如果还是不行,试试这个:@ViewChild('table') table: MatTable&lt;Element&gt;;
  • “在 Angular 9 及更高版本中,删除任何 {static: false} 标志是安全的,我们将在示意图中为您进行清理。”声明here。
【解决方案2】:

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

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

要从 Typescrypt 代码调用材料表组件上的方法,您需要通过对表的 ViewChild 引用来执行此操作。首先在模板中的表中添加一个带井号的名称:

<table #myTable mat-table ... >

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

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

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

所以现在你可以这样做了:

this.myTable.renderRows();   

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

【讨论】:

    【解决方案3】:

    @ViewChild('myTable') myTable: MatTableModule

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

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

    @ViewChild(MatTable) matTable: MatTable
    

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

    【讨论】:

    • 那只是返回'MatTable is undefined'。
    • 你必须将它从材料模块导入到你的文件中,如果它甚至以这种方式命名的话。你想通过ViewChild查询什么组件?
    • 我正在尝试访问 Table 组件上的 renderRows() 方法 - material.angular.io/components/table/overview
    • 所以像我之前解释的那样查询MatTable。
    • MatTable 仍未定义。
    【解决方案4】:

    你可以使用

    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-10-07
      • 2018-07-06
      • 2018-06-17
      • 1970-01-01
      • 2018-09-02
      • 2018-07-16
      • 2019-04-22
      • 2021-10-04
      • 2018-02-16
      相关资源
      最近更新 更多