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

ag-grid自定义单元格渲染器水平来回滚动后服务显示undefined问题

问题根因

ag-grid v26 默认开启单元格虚拟化能力,滚动时会销毁离开可视区域的单元格组件,再次滚回对应位置时会重新创建组件实例。如果自定义渲染器没有被Angular的依赖注入容器识别为动态组件,ag-grid创建实例时就不会自动注入构造函数声明的服务,导致服务变为undefined。

可行解决方案

方案1:修正自定义渲染器的注册与实现(推荐,不影响虚拟化性能)

  • 首先确保自定义单元格渲染器实现ICellRendererAngularComp接口:
import { ICellRendererAngularComp } from 'ag-grid-angular';
import { Component } from '@angular/core';

@Component({
  selector: 'app-status-renderer',
  template: `` // 你的原有模板逻辑
})
export class StatusRendererComponent implements ICellRendererAngularComp {
  // 原有注入逻辑保留
  constructor(
    protected readonly permissionService: NgxPermissionsService,
    private readonly translateService: LanguageTranslateService,
  ) {}

  // 必须实现的接口方法
  agInit(params: any): void {
    // 初始化参数逻辑写在这里
  }

  refresh(params: any): boolean {
    return false;
  }
}
  • 第二步:在引入AgGridModule的地方传入自定义渲染器组件,同时在模块的entryComponents数组中声明组件:
import { AgGridModule } from 'ag-grid-angular';

@NgModule({
  imports: [
    // 其他模块导入
    AgGridModule.withComponents([StatusRendererComponent, ColumnHeaderRendererComponent])
  ],
  declarations: [
    StatusRendererComponent,
    ColumnHeaderRendererComponent
  ],
  entryComponents: [ // Angular 10需要显式声明动态渲染的组件
    StatusRendererComponent,
    ColumnHeaderRendererComponent
  ],
  // 其他模块配置省略
})
export class YourModule {}
  • 第三步:保留原有frameworkComponents配置即可,无需额外修改表格配置

方案2:关闭单元格虚拟化(临时验证用,不推荐生产环境使用,会降低大表格性能)

如果需要快速验证问题是否由虚拟化导致,可在gridOptions中添加配置关闭单元格虚拟化:

public gridOptions = {
  // 其他原有配置
  suppressCellVirtualisation: true,
  // 列配置等其他项
}

关闭后ag-grid会缓存所有单元格组件实例,不会在滚动时销毁,服务实例会正常保留,但表格数据量大的时候会出现明显卡顿。

方案3:主动通过Injector获取服务(兜底方案)

如果以上方案都不生效,可以在渲染器中直接注入Angular根注入器,主动获取服务实例,避免构造函数注入失效:

import { Injector } from '@angular/core';
import { ICellRendererAngularComp } from 'ag-grid-angular';

export class StatusRendererComponent implements ICellRendererAngularComp {
  private permissionService: NgxPermissionsService;
  private translateService: LanguageTranslateService;

  constructor(private injector: Injector) {
    // 主动从注入器获取服务实例
    this.permissionService = this.injector.get(NgxPermissionsService);
    this.translateService = this.injector.get(LanguageTranslateService);
  }

  // 其他接口方法省略
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 10:54:04