如何在AG Grid中获取新增及更新的行数据
解决ag-Grid获取新增/修改行的问题
嘿,我来帮你搞定这个ag-Grid保存变更的问题~你之前遇到的includes判断失效,核心原因是对象是引用类型——哪怕两个对象内容完全一样,只要不是同一个引用,includes就会返回false,所以你的对比逻辑根本起不了作用。下面给你两种靠谱的解决方案,按需选就行:
方案一:给行数据加状态标记(推荐,更高效)
这种方法是在新增和修改行的时候,给数据打上明确的状态标记,后续直接筛选这些标记行即可,逻辑简单且性能好。
1. 新增行时标记状态
修改你的createNewRowData方法,给新增的行加上isNew标识:
createNewRowData(){ // 返回带标记的空行数据 return { FUND_CODE: "", PORT_CODE: "", isNew: true, // 标记为新增行 isModified: false }; }
2. 监听单元格修改,标记已变更行
在ag-Grid的配置里加上onCellValueChanged事件,当单元格内容修改时,给非新增行打上isModified标记:
// 初始化gridOptions的时候配置 this.gridOptions = { // 你的其他grid配置... onCellValueChanged: (params) => { // 只有非新增行才需要标记为已修改 if (!params.data.isNew) { params.data.isModified = true; } } };
3. 保存时筛选变更行
在saveChanges方法里,遍历所有行节点,筛选出带isNew或isModified标记的行,再传给后端:
saveChanges(){ const changedRows = []; // 遍历所有行节点 this.gridOptions.api.forEachNode((rowNode) => { const rowData = rowNode.data; // 筛选新增或修改过的行 if (rowData.isNew || rowData.isModified) { // 移除标记属性,避免传给后端(如果不需要的话) const { isNew, isModified, ...cleanData } = rowData; changedRows.push(cleanData); } }); // 调用服务保存数据 this.myAppService.saveData(changedRows).subscribe( (response) => { console.log("Saved successfully to database"); // 保存成功后,更新初始数据并清除标记 this.tableData = JSON.parse(JSON.stringify(changedRows)); this.gridOptions.api.forEachNode((rowNode) => { delete rowNode.data.isNew; delete rowNode.data.isModified; }); }, (error) => { console.error("Save failed:", error); } ); }
方案二:对比初始数据与当前数据(适合无法加标记的场景)
如果不能给行数据加额外属性,可以通过深拷贝初始数据,再对比内容来判断新增和修改行。
1. 初始加载时深拷贝数据
在retrieveTableData方法里,对从后端获取的数据做深拷贝,避免引用关联:
retrieveTableData (){ this.myAppService.getTableData().subscribe(data => { // 深拷贝初始数据,确保和当前行数据是独立引用 this.tableData = JSON.parse(JSON.stringify(data)); // 把数据传给ag-Grid this.gridOptions.api.setRowData(data); }); }
2. 保存时对比数据
通过联合标识(比如你的FUND_CODE+PORT_CODE)判断是否为新增行,再对比内容判断是否为修改行:
saveChanges(){ // 获取当前所有行数据 const currentRows = []; this.gridOptions.api.forEachNode((rowNode) => { currentRows.push(rowNode.data); }); const changedRows = []; // 生成初始数据的标识集合(用来判断新增行) const initialIdentifiers = this.tableData.map(item => `${item.FUND_CODE}-${item.PORT_CODE}`); // 筛选新增行:当前行的标识不在初始集合里 const newRows = currentRows.filter(row => { const currentId = `${row.FUND_CODE}-${row.PORT_CODE}`; return !initialIdentifiers.includes(currentId); }); // 筛选修改行:初始数据存在,但内容有变化 const modifiedRows = currentRows.filter(row => { const currentId = `${row.FUND_CODE}-${row.PORT_CODE}`; const initialRow = this.tableData.find(item => `${item.FUND_CODE}-${item.PORT_CODE}` === currentId); if (!initialRow) return false; // 跳过新增行 // 对比所有字段内容是否一致(简单场景用JSON.stringify,复杂场景可以逐个字段对比) return JSON.stringify(row) !== JSON.stringify(initialRow); }); // 合并新增和修改行 changedRows.push(...newRows, ...modifiedRows); // 保存到后端 this.myAppService.saveData(changedRows).subscribe( () => { console.log("Saved successfully to database"); // 更新初始数据为当前最新数据 this.tableData = JSON.parse(JSON.stringify(currentRows)); }, (err) => console.error("Save error:", err) ); }
为什么你之前的代码失效?
你用this.tableData.includes(item)判断的时候,item是当前行的对象,而tableData里的对象是初始加载时的引用——哪怕内容完全一样,它们也是两个不同的对象,所以includes永远返回false。必须通过标识对比或者内容对比,而不是直接对比对象引用。
内容的提问来源于stack exchange,提问作者xzk
相关产品推荐
相关产品推荐

