Bootstrap Table同步复选框勾选时触发Maximum Call Stack Size Exceeded错误求助
问题分析与解决方案
错误原因
你遇到的Maximum Call Stack Size Exceeded是无限递归调用导致的,核心问题有两个:
- 循环事件触发:如果
#gridModalListeDossiers也绑定了类似的同步勾选事件(比如勾选时同步回#gridDossiers),两个表格的check.bs.table事件会互相触发,形成无限循环,最终撑爆调用栈。 - 冗余操作放大问题:你的代码在单个行勾选时,遍历整个表格的所有行,重复勾选已选中的行。即使没有反向同步,这种重复调用
bootstrapTable('check')的行为也会多次触发check.bs.table事件,加剧递归触发的概率。
解决方案
1. 加入同步标志位,阻断递归循环
添加一个全局标志位,标记当前是否正在执行同步操作,避免事件重复触发:
// 定义同步标志位 let isSyncing = false; $('#gridDossiers').on('check.bs.table', lang.hitch(this, function(row, $element) { // 如果正在同步,直接返回,避免递归触发 if (isSyncing) return; isSyncing = true; // 只同步当前被勾选的行,而非遍历所有行 const rowIndex = $('#gridDossiers').bootstrapTable('getRowIndex', row); $('#gridModalListeDossiers').bootstrapTable('check', rowIndex); // 同步完成后重置标志位 isSyncing = false; })); // 若存在反向同步(#gridModalListeDossiers勾选时同步回#gridDossiers),同样添加标志位 $('#gridModalListeDossiers').on('check.bs.table', lang.hitch(this, function(row, $element) { if (isSyncing) return; isSyncing = true; const rowIndex = $('#gridModalListeDossiers').bootstrapTable('getRowIndex', row); $('#gridDossiers').bootstrapTable('check', rowIndex); isSyncing = false; }));
2. 用唯一标识符匹配行(更可靠)
如果两个表格的行顺序可能不一致,不要用索引匹配,改用行数据的唯一标识符(比如id字段)定位目标行,避免同步错误:
let isSyncing = false; $('#gridDossiers').on('check.bs.table', lang.hitch(this, function(row, $element) { if (isSyncing) return; isSyncing = true; const targetTable = $('#gridModalListeDossiers'); // 假设行数据的唯一标识字段为id const targetRow = targetTable.bootstrapTable('getRowByUniqueId', row.id); if (targetRow) { const targetIndex = targetTable.bootstrapTable('getRowIndex', targetRow); targetTable.bootstrapTable('check', targetIndex); } isSyncing = false; }));
3. 移除冗余遍历逻辑
原代码中遍历整个表格的操作完全没必要,只需要处理当前被勾选的行即可,这样能大幅减少不必要的事件触发,避免递归风险。
内容的提问来源于stack exchange,提问作者Achraf
相关产品推荐
相关产品推荐

