You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular12调用CdkTable的renderRows时报undefined属性读取错误如何解决

问题原因

你遇到的Cannot read property 'renderRows' of undefined错误,核心原因是Angular的@ViewChild查询结果在ngOnInit生命周期阶段还未完成初始化。ngOnInit触发时组件的DOM模板还没有完成渲染挂载,此时通过@ViewChild查询到的DOM/组件实例仍然是undefined,访问其属性自然会触发报错。

另外你代码中CdkTable<string>的泛型定义和实际数据源类型PeriodicElement不匹配,也可能后续引发类型相关报错。

修复步骤
  • 将操作cdkTable实例的逻辑从ngOnInit迁移到ngAfterViewInit生命周期钩子中,该钩子会在组件视图完全渲染完成后触发,此时@ViewChild的查询结果已经完成赋值。
  • 检查组件模板代码,确认<cdk-table>标签上添加了#cdkTable模板引用变量,否则@ViewChild无法匹配到对应的cdkTable实例。
  • 修正CdkTable的泛型定义,和你的数据源类型保持一致。

可选说明:如果有特殊场景需要在ngOnInit阶段访问cdkTable实例,且你的cdkTable在模板中不是被*ngIf等条件渲染控制的,可以修改@ViewChild配置为@ViewChild('cdkTable', {static: true}) cdkTable!: CdkTable<PeriodicElement>;,这种情况下查询结果会在ngOnInit前完成初始化。不过更推荐优先使用ngAfterViewInit方案,适用场景更广。

修改后的核心代码示例
// 首先导入AfterViewInit接口
import { Component, OnInit, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import {DataSource} from '@angular/cdk/collections';
import {BehaviorSubject, Observable} from 'rxjs';
import { CdkTable } from '@angular/cdk/table';


export interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  symbol: string;
}

const ELEMENT_DATA: PeriodicElement[] = [
  {position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H'},
  {position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'},
  {position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li'},
  {position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be'},
  {position: 5, name: 'Boron', weight: 10.811, symbol: 'B'},
  {position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C'},
  {position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N'},
  {position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O'},
  {position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F'},
  {position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne'},
];

@Component({
  selector: 'app-cdk-table-basic-example',
  templateUrl: './cdk-table-basic-example.component.html',
  styleUrls: ['./cdk-table-basic-example.component.css']
})
export class CdkTableBasicExampleComponent implements OnInit, AfterViewInit {
  // 修正泛型为PeriodicElement
  @ViewChild('cdkTable') cdkTable!: CdkTable<PeriodicElement>;
  @ViewChild('cdkTable', {read: ElementRef}) cdkTableElement!: ElementRef;
  
  constructor() { 
  }

  ngOnInit(): void {
    // 原cdkTable相关逻辑移除
  }

  ngAfterViewInit(): void {
    // 把原逻辑移到此处,增加bind避免this指向异常
    const org_renderRows = this.cdkTable.renderRows.bind(this.cdkTable);
    this.cdkTable.renderRows = () => {
      console.debug('#renderRows');
      org_renderRows();
      const rows = this.cdkTable._getRenderedRows(this.cdkTable._rowOutlet);
      console.debug('#renderRows - rows count: ' + rows.length);
      if (rows.length > 0) {
         console.debug('Scroll to the End is ON - auto-scroll down to latest metric');
        rows[rows.length - 1].scrollIntoView(false);
      } else {
        console.debug('Scroll to the End is OFF - don\'t auto-scroll'); 
      }
    };
  }

  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
  dataSource = new ExampleDataSource();
}

export class ExampleDataSource extends DataSource<PeriodicElement> {
  data = new BehaviorSubject<PeriodicElement[]>(ELEMENT_DATA);

  connect(): Observable<PeriodicElement[]> {
    return this.data;
  }

  disconnect() {}
}

内容的提问来源于stack exchange,提问作者vrreddy1234

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 01:54:07