AG Grid企业版实现十六进制编辑器类文本的连续单元格选择问题
AG Grid实现十六进制编辑器跨行连续选择的解决方案
问题原因
你当前实现无法继续选择的核心问题是:onRangeSelectionChanged回调会在你调用clearRangeSelection、addCellRange操作选择范围时再次被触发,形成无限触发循环,导致选择状态被锁死。同时你的逻辑中存在边界错误:当startRow > stopRow时,你写的for(var i = startRow + 1; i<stopRow - 1; i++)循环条件永远不成立,中间行不会被选中。
修正后的实现方案
首先添加执行锁避免循环触发,再修正行列遍历逻辑:
const gridOptions = { // ... 其他配置 enableRangeSelection: true, // 加锁避免回调循环触发 isProcessingSelection: false, onRangeSelectionChanged: function(event) { // 正在处理中直接返回,避免循环 if (gridOptions.isProcessingSelection) return; gridOptions.isProcessingSelection = true; const ranges = gridOptions.api.getCellRanges(); if (!ranges || ranges.length === 0) { gridOptions.isProcessingSelection = false; return; } const range = ranges[0]; let startRow = range.startRow.rowIndex; let stopRow = range.endRow.rowIndex; const startCol = range.startColumn; const endCol = range.columns[range.columns.length - 1]; const firstCol = gridOptions.columnApi.getColumn("hex0"); const lastCol = gridOptions.columnApi.getColumn("hex15"); // 同行业务逻辑不变 if (startRow === stopRow) { gridOptions.isProcessingSelection = false; return; } // 先统一处理行顺序,避免start > stop的逻辑分支重复 let minRow = Math.min(startRow, stopRow); let maxRow = Math.max(startRow, stopRow); let isUpwardSelect = startRow > stopRow; // 清空原有选择 gridOptions.api.clearRangeSelection(); if (isUpwardSelect) { // 向上选择:起始行(靠下的行)选起始列到最左 gridOptions.api.addCellRange({ rowStartIndex: startRow, rowEndIndex: startRow, columnStart: firstCol, columnEnd: startCol, }); // 中间行全选 for (let i = minRow + 1; i < maxRow; i++) { gridOptions.api.addCellRange({ rowStartIndex: i, rowEndIndex: i, columnStart: firstCol, columnEnd: lastCol, }); } // 结束行(靠上的行)选最右到结束列 gridOptions.api.addCellRange({ rowStartIndex: stopRow, rowEndIndex: stopRow, columnStart: endCol, columnEnd: lastCol, }); } else { // 向下选择:起始行选起始列到最右 gridOptions.api.addCellRange({ rowStartIndex: startRow, rowEndIndex: startRow, columnStart: startCol, columnEnd: lastCol, }); // 中间行全选 for (let i = minRow + 1; i < maxRow; i++) { gridOptions.api.addCellRange({ rowStartIndex: i, rowEndIndex: i, columnStart: firstCol, columnEnd: lastCol, }); } // 结束行选最左到结束列 gridOptions.api.addCellRange({ rowStartIndex: stopRow, rowEndIndex: stopRow, columnStart: firstCol, columnEnd: endCol, }); } // 处理完成解锁 gridOptions.isProcessingSelection = false; } }
可选替代方案(更稳定)
如果原生range选择的修改容易出现冲突,可以放弃原生range选择,改用自定义选择逻辑:
- 关闭
enableRangeSelection,监听cellMouseDown、cellMouseOver、cellMouseUp事件 - 自定义变量存储选择的起始、结束单元格坐标
- 用
cellClassRules给坐标范围内的单元格添加选中样式
这种方式完全自己控制选择逻辑,不会和AG Grid原生逻辑冲突,更适合十六进制编辑器这类定制化选择场景。
内容的提问来源于stack exchange,提问作者Fee
相关产品推荐
相关产品推荐

