Angular中ag-grid单元格渲染器重渲染后如何保留输入框原值?
嗨,这个问题我之前在做Angular+Ag-Grid项目的时候也踩过坑!核心原因是Ag-Grid为了性能优化,会对移出视口的单元格进行虚拟化销毁,当你滚动回来时重新创建渲染组件——如果输入值只存在于组件/输入框的本地状态,没有同步到Ag-Grid的数据源里,重建后自然就丢失了。
下面是具体的解决方案,一步步来:
解决Ag-Grid自定义单元格渲染器滚动丢失输入值的问题
1. 核心原则:把输入值绑定到数据源
所有用户输入必须双向绑定到Ag-Grid的params.data对象(也就是你的行数据源),而不是组件内部的临时变量。这是Ag-Grid唯一的可信数据源,不会随组件销毁而丢失。
比如你的模板应该这么写(假设行数据里有inputContent字段):
<!-- 你的ngTemplate内容 --> <input type="text" [(ngModel)]="params.data.inputContent" />
如果用响应式表单,也要确保表单控件的值同步到params.data:
<input type="text" [formControl]="inputCtrl" (ngModelChange)="updateData($event)" />
// 组件内同步数据的方法 updateData(value: string) { this.currentParams.data.inputContent = value; }
2. 优化你的单元格渲染器组件
你的现有组件可以调整,确保上下文引用稳定,避免不必要的组件重建:
import { Component, TemplateRef } from '@angular/core'; import { ICellRendererAngularComp, ICellRendererParams } from 'ag-grid-angular'; export class TemplateRendererComponent implements ICellRendererAngularComp { template: TemplateRef<any>; templateContext: { $implicit: any, params: ICellRendererParams }; // 保存当前params的引用,避免每次refresh都重新创建上下文 private currentParams: ICellRendererParams; agInit(params: ICellRendererParams): void { this.currentParams = params; this.template = params['ngTemplate']; this.updateTemplateContext(); } refresh(params: ICellRendererParams): boolean { // 只有当数据源变化时才更新上下文,减少无意义的刷新 if (params.data !== this.currentParams.data) { this.currentParams = params; this.updateTemplateContext(); } // 返回false表示不需要重建组件,只更新上下文即可 return false; } private updateTemplateContext(): void { this.templateContext = { $implicit: this.currentParams.data, params: this.currentParams }; } }
3. 可选:禁用列虚拟化(仅小数据量场景)
如果你的表格列数很少、数据量极小,可以通过关闭Ag-Grid的列虚拟化来避免组件销毁,但这会牺牲性能,不推荐大数据量使用:
<ag-grid-angular [suppressColumnVirtualization]="true" <!-- 其他Ag-Grid配置 --> ></ag-grid-angular>
关键注意点
- 绝对不要把输入值存在渲染组件的内部属性里,组件随时可能被Ag-Grid销毁回收;
- 如果需要手动触发单元格刷新,可以调用Ag-Grid的API:
this.currentParams.api.refreshCells({ rowNodes: [this.currentParams.node], columns: [this.currentParams.column.colId] });
内容的提问来源于stack exchange,提问作者over_stack_flow
相关产品推荐
相关产品推荐

