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

jQuery DataTable重复数据问题:新增记录时保留旧数据如何解决?

问题分析

你遇到的重复行问题,核心原因是重复绑定了点击事件。每次调用drawDataTable函数时,你都会给隐藏按钮#addRows绑定一次click事件,但之前绑定的事件并没有被移除。这样多次调用后,执行$('#addRows').click()时,会触发所有历史绑定的事件,导致旧数据被重复添加,和新数据叠加出现重复行。

另外,虽然你调用了table.destroy()销毁旧实例,但DOM上的事件绑定不会随着DataTable实例销毁而自动移除,这也是问题的关键所在。

解决方案

这里提供几种可行的修复方式,按推荐程度排序:

方案1:直接用DataTable的data选项初始化数据(最简洁高效)

不需要借助隐藏按钮触发添加行,直接在初始化DataTable时传入整组数据,这也是DataTable官方推荐的用法:

function drawDataTable(pData) {
  console.log("Call of drawDataTable!!!");
  // 显示表格卡片
  document.getElementById("dataTableCard").style.display = "block";

  // 销毁旧的DataTable实例
  const table = $('#dataTable').DataTable();
  table.destroy();

  // 把pData转换成DataTable需要的二维数组格式
  const p1 = pData['p1'];
  const p2 = pData['p2'];
  const p3 = pData['p3'];
  const p4 = pData['p4'];
  const p5 = pData['p5'];
  const p6 = pData['p6'];
  
  const tableData = [];
  for (const idxT in p1) {
    tableData.push([
      p1[idxT],
      p2[idxT],
      p3[idxT],
      p4[idxT],
      p5[idxT],
      p6[idxT]
    ]);
  }

  // 初始化新表格,直接传入数据
  $('#dataTable').DataTable({
    "scrollY": "400px",
    "paging": false,
    "data": tableData // 这里直接传入整理好的数据
  });
}

方案2:绑定事件前先解绑旧事件

如果你坚持要保留隐藏按钮的逻辑,需要在每次绑定新事件前,移除之前绑定的所有click事件:

function drawDataTable(pData) {
  console.log("Call of drawDataTable!!!");
  document.getElementById("dataTableCard").style.display = "block";

  const table = $('#dataTable').DataTable();
  table.destroy();

  const newTable = $('#dataTable').DataTable({
    "scrollY": "400px",
    "paging": false
  });

  const p1 = pData['p1'];
  const p2 = pData['p2'];
  const p3 = pData['p3'];
  const p4 = pData['p4'];
  const p5 = pData['p5'];
  const p6 = pData['p6'];

  // 关键:先解绑所有click事件,再绑定新的
  $('#addRows').off('click').on('click', function() {
    // 清空现有行(可选,确保万无一失)
    newTable.clear();
    for (const idxT in p1) {
      newTable.row.add([
        p1[idxT],
        p2[idxT],
        p3[idxT],
        p4[idxT],
        p5[idxT],
        p6[idxT]
      ]).draw(false);
    }
  });

  $('#addRows').click();
}

这里额外加上了newTable.clear(),可以确保添加新数据前表格是空的,双重保障避免重复。

方案3:使用事件委托(适合频繁创建销毁实例的场景)

把事件绑定到父元素上,利用事件委托机制,避免重复绑定:

// 只需要在页面初始化时绑定一次,不用放在drawDataTable里
$('#dataTableCard').on('click', '#addRows', function() {
  const table = $('#dataTable').DataTable();
  table.clear();
  // 从按钮的data属性中获取当前要加载的数据
  const pData = $(this).data('tableData');
  const p1 = pData['p1'];
  const p2 = pData['p2'];
  const p3 = pData['p3'];
  const p4 = pData['p4'];
  const p5 = pData['p5'];
  const p6 = pData['p6'];
  
  for (const idxT in p1) {
    table.row.add([
      p1[idxT],
      p2[idxT],
      p3[idxT],
      p4[idxT],
      p5[idxT],
      p6[idxT]
    ]).draw(false);
  }
});

function drawDataTable(pData) {
  console.log("Call of drawDataTable!!!");
  document.getElementById("dataTableCard").style.display = "block";

  const table = $('#dataTable').DataTable();
  table.destroy();

  $('#dataTable').DataTable({
    "scrollY": "400px",
    "paging": false
  });

  // 把pData存在按钮的data属性里,供事件委托的回调使用
  $('#addRows').data('tableData', pData);
  $('#addRows').click();
}

这种方式适合表格频繁创建销毁的场景,避免重复绑定事件的问题。

总结

最推荐方案1,既符合DataTable的设计逻辑,又能彻底避免事件绑定带来的问题,代码也更简洁易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:08:31