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
相关产品推荐
相关产品推荐

