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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:59:05