React+TypeScript环境下,如何在AgGrid中遍历选中单元格?
在React + TypeScript的AgGrid中实现按键清空选中单元格
要实现按下Backspace/Delete键清空选中单元格,核心是获取选中单元格列表并遍历更新数据,以下是具体实现步骤和代码:
1. 配置Grid基础参数
首先确保Grid开启单元格多选功能,在AgGridReact组件中配置cellSelection="multiple",这是多选单元格的前提:
import { AgGridReact, AgGridColumn } from 'ag-grid-react'; import 'ag-grid-community/styles/ag-grid.css'; import 'ag-grid-community/styles/ag-theme-alpine.css'; import { useRef, useEffect, useState } from 'react'; // 定义你的数据类型 interface RowDataType { id: number; name: string; age: string; address: string; } export default function ClearSelectedCellsGrid() { const gridRef = useRef<AgGridReact<RowDataType>>(null); const [rowData, setRowData] = useState<RowDataType[]>([ { id: 1, name: '张三', age: '25', address: '北京' }, { id: 2, name: '李四', age: '30', address: '上海' }, { id: 3, name: '王五', age: '28', address: '广州' }, ]); const columnDefs = [ { field: 'id', headerName: 'ID', editable: true }, { field: 'name', headerName: '姓名', editable: true }, { field: 'age', headerName: '年龄', editable: true }, { field: 'address', headerName: '地址', editable: true }, ]; // 2. 绑定键盘事件处理逻辑 useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { // 仅当事件触发源在Grid内部时处理,避免全局干扰 const gridPanel = gridRef.current?.api?.getGridPanelElement(); if (!gridPanel || !gridPanel.contains(e.target as Node)) return; // 判断是否为Backspace或Delete键 if (e.key === 'Backspace' || e.key === 'Delete') { e.preventDefault(); // 阻止默认行为(如删除输入框文本) // 获取所有选中的单元格 const selectedCells = gridRef.current?.api.getSelectedCells(); if (!selectedCells || selectedCells.length === 0) return; // 3. 遍历选中单元格,清空对应值 const updatedRowData = [...rowData]; selectedCells.forEach(cell => { const rowIndex = cell.rowNode.rowIndex; const field = cell.colDef.field; // 确保行索引和字段有效时更新 if (rowIndex !== undefined && field) { updatedRowData[rowIndex] = { ...updatedRowData[rowIndex], [field]: '' // 可根据需求改为null或其他空值 }; } }); // 更新数据状态 setRowData(updatedRowData); // 4. 刷新Grid视图,确保单元格显示最新值 gridRef.current?.api.refreshCells({ force: true, columns: selectedCells.map(cell => cell.colDef.field) }); } }; document.addEventListener('keydown', handleKeyDown); // 组件卸载时移除事件监听 return () => document.removeEventListener('keydown', handleKeyDown); }, [rowData]); return ( <div className="ag-theme-alpine" style={{ height: 400 }}> <AgGridReact ref={gridRef} rowData={rowData} columnDefs={columnDefs} cellSelection="multiple" // 开启单元格多选 enableCellTextSelection={true} // 可选:允许选中文本(不影响多选) editable={true} // 可选:如果需要单元格可编辑 /> </div> ); }
关键逻辑说明
- 获取选中单元格:通过Grid API的
getSelectedCells()方法,返回所有选中单元格的数组,每个元素包含rowNode(行节点)和colDef(列定义)。 - 遍历更新数据:对每个选中单元格,通过
rowNode.rowIndex定位到数据数组中的对应行,再通过colDef.field找到要清空的字段,创建新的数据对象(遵循React不可变数据原则)。 - 刷新视图:调用
refreshCells()强制更新选中的单元格,确保视图及时同步。
注意事项
- 必须设置
cellSelection="multiple",否则无法多选单元格。 - 事件监听时添加了Grid范围判断,避免在页面其他输入框按下按键时触发清空逻辑。
- 如果使用虚拟滚动(
pagination或rowModelType="infinite"),rowNode.rowIndex可能不准确,此时可以通过rowNode.data直接定位数据,例如:
这种方式不需要依赖selectedCells.forEach(cell => { const field = cell.colDef.field; if (field) { cell.rowNode.data[field] = ''; } }); gridRef.current?.api.refreshCells({ force: true });rowIndex,更适合虚拟滚动场景。
内容的提问来源于stack exchange,提问作者cedd
相关产品推荐
相关产品推荐

