Ag-Grid V18.1中onCellFocus与排序功能兼容异常问题咨询
Ag-Grid V18.1 排序后onCellFocus事件失效:DOM焦点不匹配问题修复
我们的应用基于自定义Ag-Grid V18.1组件开发,当onCellFocus事件与排序功能组合使用时出现异常——排序后聚焦单元格时无法正确定位DOM元素,焦点设置失效。核心原因是排序后网格行的rowIndex会发生变化,原代码中通过e.column.getId() + e.rowIndex拼接DOM ID的方式,会导致定位到的元素和实际聚焦的单元格不匹配。
原问题代码
onCellFocused = (e) => { if (e.rowIndex !== null) { const selectedData = this.gridChild.getSelectedRows(); let pin = 0; if(selectedData !== undefined) { selectedData.map(row => { pin = row.pin; }); } this.bindTechSpecLineItems(pin, e); if(e.column.getId() === 'expenseDate' || e.column.getId() === 'expenseDescription') { this.setState({ isReloadGrid : true }); } else { this.setState({ isReloadGrid : false }); } if(document.getElementById(e.column.getId() + e.rowIndex) !== null) { if(document.getElementById(e.column.getId() + e.rowIndex).type === 'text') { document.getElementById(e.column.getId() + e.rowIndex).select(); } else if(document.getElementById(e.column.getId() + e.rowIndex).type === 'select-one') { if(e.forceBrowserFocus) document.getElementById(e.column.getId() + e.rowIndex).focus(); else document.getElementById(e.column.getId() + e.rowIndex).click(); } else { document.getElementById(e.column.getId() + e.rowIndex).focus(); } } } }
表头配置
{ "rowSelection": 'multiple', "pagination": false, "enableFilter": false, "enableSorting": true, "searchable": false, "gridActions": true, "gridTitlePanel": false, "headerHeight":40 }
修复方案
核心思路是放弃依赖rowIndex定位DOM,改用Ag-Grid提供的API获取单元格实例,同时优化行数据的获取逻辑:
onCellFocused = (e) => { if (e.rowIndex === null) return; // 直接从当前聚焦行获取pin,无需遍历所有选中行 const focusedRowData = e.rowData; const pin = focusedRowData?.pin || 0; this.bindTechSpecLineItems(pin, e); // 简化状态更新逻辑 const shouldReload = ['expenseDate', 'expenseDescription'].includes(e.column.getId()); this.setState({ isReloadGrid: shouldReload }); // 用Ag-Grid API获取单元格DOM,彻底摆脱rowIndex依赖 const cellRenderer = e.api.getCellRendererInstances({ rowNodes: [e.node], columns: [e.column] })[0]; if (!cellRenderer) return; const cellDom = cellRenderer.getGui(); const inputElement = cellDom.querySelector('input, select'); if (!inputElement) return; // 根据元素类型处理焦点/选中逻辑 if (inputElement.type === 'text') { inputElement.select(); } else if (inputElement.type === 'select-one') { e.forceBrowserFocus ? inputElement.focus() : inputElement.click(); } else { inputElement.focus(); } }
关键修改点
- 行数据获取优化:直接从
e.rowData拿到当前聚焦行的pin,不用遍历选中行(原逻辑会覆盖pin值,只保留最后一个选中行的pin,逻辑错误) - DOM定位方式替换:用
getCellRendererInstances通过rowNode和column获取单元格实例,再通过getGui()拿到DOM元素,排序后依然能精准定位 - 简化条件判断:用数组
includes替代多条件判断,代码更简洁 - 避免重复DOM查询:只查询一次DOM元素,提升性能
额外优化建议
为了让Ag-Grid更稳定地识别行,建议在gridOptions中配置行唯一标识:
// 添加到表头配置中 "getRowId": params => params.data.pin // 假设pin是每行的唯一ID
内容的提问来源于stack exchange,提问作者Balaji N
相关产品推荐
相关产品推荐

