模态框内DataTable开关仅首次生效无法获取行数据如何解决
问题根因
你遇到的问题核心是事件重复绑定+旧DataTable实例残留引用,具体原因如下:
- 每次调用
ReloadDataTableModal重载表格时,都会重新给#TableDiseasesUser tbody绑定一次开关的点击事件,但没有清理上一次绑定的旧事件。第二次点击开关时,会先后触发新旧两个事件处理函数:旧函数引用的tableModal实例已经被销毁,调用row()方法无法获取到行数据,就会返回undefined。 - DataTable销毁时只调用了
clear()和destroy(),没有清空表格内部的DOM节点,可能导致新老实例的行元素识别冲突。
修复方案
直接修改ReloadDataTableModal函数即可,修改后的代码如下:
function ReloadDataTableModal(response) { // 1. 先解绑之前绑定的开关点击事件,避免重复触发 $('#TableDiseasesUser tbody').off('click', 'input.toggle-disease'); // 2. 彻底销毁旧DataTable实例+清空DOM if ($.fn.DataTable.isDataTable('#TableDiseasesUser')) { $('#TableDiseasesUser').DataTable().destroy(); } $('#TableDiseasesUser tbody').empty(); // 3. 初始化新表格实例 var tableModal = $('#TableDiseasesUser').DataTable({ "processing": true, "responsive": true, "destroy": true, data: response, "columns": [ { "data": "diseaseId", "autoWidth": true }, { "data": "diseaseName", "autoWidth": true }, { "data": "diseasedStatus", render: getToggleSwitch }, ], fixedColumns: { heightMatch: 'none' }, "language": { "url": "//cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Spanish.json" }, "aLengthMenu": [ [25, 50, 100, 200, -1], [25, 50, 100, 200, "Todos"] ] }); // 4. 绑定新的点击事件,直接获取当前最新实例,避免闭包引用旧实例 $('#TableDiseasesUser tbody').on("click", "input.toggle-disease", function () { var currentTable = $('#TableDiseasesUser').DataTable(); // 用closest替代parents,精准匹配最近的tr父元素 var data = currentTable.row($(this).closest("tr")).data(); ActionAddDiseaseToUser(data); }); }
补充优化说明
- 用
$.fn.DataTable.isDataTable判断表格是否已经是DataTable实例,避免销毁不存在的实例报错 - 事件处理函数内直接获取当前最新的表格实例,不依赖闭包保存的
tableModal变量,彻底规避旧实例引用问题 closest("tr")比parents("tr")精准度更高,只会返回距离当前元素最近的tr父节点,避免嵌套结构下匹配错误
内容的提问来源于stack exchange,提问作者Cristofher Ambiado
相关产品推荐
相关产品推荐

