ag-Grid 中的编辑相关属性和 API 相当多,下面我会根据编辑行为控制,编辑事件和回调、编辑操作、数据操作等方面进行分类说明:
1. 编辑行为控制
1.1 editable
- 描述: 指定列是否可编辑。
- **类型:**
boolean |(params: ColDef) => boolean -
// 列定义中设置 editable 属性 const columnDefs = [ { headerName: 'Name', field: 'name', editable: true }, // 其他列配置... ]; // 默认列定义中设置,默认列定义定义的属性会在每一列中都生效,除非被列定义中覆盖 const defaultColDef = { editable: (params) => true }; <AgGridReact defaultColDef={defaultColDef} columnDefs={columnDefs} // 其他配置... />
1.2 singleClickEdit
- 描述: 是否允许单击即可进入编辑模式。默认为双击进入编辑模式
- **类型:**
boolean -
// 启用单击即可进入编辑模式 <AgGridReact singleClickEdit={true} // 其他配置... />
1.3 suppressClickEdit
- 描述: 禁止通过单击单元格进入编辑模式。可以和
singleClickEdit搭配使用,实现全局是否可编辑的功能。 - **类型:**
boolean -
// 禁止通过单击单元格进入编辑模式 <AgGridReact suppressClickEdit={true} // 其他配置... />
1.4 stopEditingWhenCellsLoseFocus
- 描述: 当单元格失去焦点时是否停止编辑。默认情况失去焦点后编辑框依然存在。
- **类型:**
boolean -
// 当单元格失去焦点时停止编辑 <AgGridReact stopEditingWhenCellsLoseFocus={true} // 其他配置... />
1.5 editType
- 描述: 开启行编辑,当进入编辑模式时,整行的单元格都进入编辑模式。
- 类型: "fullRow" | undefined
- 场景: 新增行数据或对需要一行数据编辑完成之后进行提交的情况使用
-
// 当单元格失去焦点时停止编辑 <AgGridReact editType="fullRow" // 其他配置... /> -
1.6 enterNavigatesVertically和enterNavigatesVerticallyAfterEdit
-
描述:
enterNavigatesVertically=true在非编辑模式下,按下Enter,焦点会移动到下方单元格,如果是false,会进入编辑模式描述:
enterNavigatesVerticallyAfterEdit=true,在编辑状态下按下 Enter 键后,焦点将移动到下方的单元格。默认情况下,编辑状态下按下 Enter 键会停止编辑,并保持焦点在编辑的单元格上。 -
**类型:**
boolean -
// 当单元格失去焦点时停止编辑 <AgGridReact enterNavigatesVertically={true} enterNavigatesVerticallyAfterEdit={true} />
2. 编辑操作
2.1 stopEditing()
- 描述: 停止编辑模式。
- **参数:**
boolean -
// 在某个按钮点击事件中停止编辑模式 const stopEditing = () => { gridApi.stopEditing(); };
2.2 startEditingCell()
- 描述: 启动指定单元格的编辑模式。可以手动设置具体的单元格开启编辑模式
- **参数:**
StartEditingCellParams -
// 在某个按钮点击事件中启动指定单元格的编辑模式 const startEditing = () => { const rowIndex = 0; // 适当设置行索引 const colKey = 'age'; // 适当设置列键 gridApi.startEditingCell({ rowIndex, colKey }); };
2.3 setSuppressKeyboardEvent()
- 描述: 设置是否禁用键盘事件来启动编辑模式。
- **参数:**
(params: SuppressKeyboardEventParams) => boolean
2.4 undoRedoCellEditing 和 undoRedoCellEditingLimit
- 描述:
undoRedoCellEditing是否启用撤销重做功能,undoRedoCellEditingLimit控制记录长度,默认为10
2.4 undoCellEditing() 和 redoCellEditing()
- 描述: 撤销和重做上一次编辑操作。
-
撤销和重做是通过监听// 撤销编辑操作的按钮点击事件 const undo = () => { gridApi.undoCellEditing(); }; // 重做编辑操作的按钮点击事件 const redo = () => { gridApi.redoCellEditing(); };onCellValueChanged事件来记录数据的,而onCellValueChanged只有用户进行的单元格变更才会触发。而applyTransaction不会触发onCellValueChanged事件,所以无法记录。
2.5 getCurrentUndoSize() 和 getCurrentRedoSize()
- 描述: 获取当前可以撤销和重做的编辑次数。
- **返回值:**
number -
// 获取当前可以撤销和重做的编辑次数 const undoSize = gridApi.getCurrentUndoSize(); const redoSize = gridApi.getCurrentRedoSize(); console.log('Undo Size:', undoSize); console.log('Redo Size:', redoSize);
2.6 getEditingCells()
- 描述: 获取当前正在编辑的单元格信息。
- 返回值: 包含正在编辑的单元格信息的数组
-
[ { "rowIndex": 1, "column": { "colId": "name", // 列的其他属性... }, "api": {...} // ag-Grid API 对象 }, // 其他正在编辑的单元格信息... ]
3. 编辑事件和回调
3.1 onCellValueChanged
- 描述: 单元格值发生变化时的回调函数。
- **参数:**
(params: NewValueParams<TData, TValue>) => void -
// 在列定义中设置 onCellValueChanged 回调函数 const columnDefs = [ { headerName: 'Age', field: 'age', editable: true, onCellValueChanged: (params) => { console.log('Cell value changed:', params.newValue); // 其他逻辑... }, }, // 其他列配置... ]; // 在AgGridReact组件中设置 onCellValueChanged 回调函数,所有单元格值发生变化都会调用 return ( <AgGridReact onCellValueChanged={(params) => { // 在单元格值发生变化时触发 const newValue = event.newValue; const oldValue = event.oldValue; const rowData = event.data; // 执行自定义逻辑... }} // 其他配置... /> )
3.2 onRowValueChanged
- 描述: 单元格值发生变化时的回调函数。只有开启了行编辑才会触发
onRowValueChanged - **参数:**
(params: RowValueChangedEvent<TData>) => void - **作用:**
onRowValueChanged函数在停止编辑后调用一次,而如果修改了多个单元格数据后onCellValueChanged则会多次调用 -
// 在AgGridReact组件中设置 onCellValueChanged 回调函数,所有单元格值发生变化都会调用 return ( <AgGridReact editType="fullRow" // 开启行编辑 onRowValueChanged(event: RowValueChangedEvent<TData>): void { // 当行内的单元格值发生变化时触发,仅适用于整行编辑 const changedRowData = event.data; // 执行自定义逻辑... } // 其他配置... /> )
4. 数据操作
4.1 setRowData()
- 描述: 更新表格数据,例如从服务器异步获取数据后更新表格
- **参数:**
(rowData: any[]) => void -
// 通过api调用setRowData,效果类似与给<AgGridReact rowData={newData} />,性能上会更好一些 api.setRowData(rowData)
4.2 applyTransaction()
-
描述:
applyTransaction的异步实现 -
**参数:**
RowDataTransaction -
作用: 它主要用于一次性应用多个数据变更,以提高性能并避免多次触发表格的刷新。它不会触发
onCellValueChanged,也不会被记录,所以无撤销操作。 -
const newData = [ { make: 'Toyota', model: 'Celica', price: 35000 }, { make: 'Ford', model: 'Mondeo', price: 32000 }, { make: 'Porsche', model: 'Boxster', price: 72000 }, ]; // 获取 grid API const gridApi = params.api; // 应用事务 gridApi.applyTransaction({ add: newData }); const onRemoveSelected = useCallback(() => { // 获取所有选中的行 var selectedRowData = gridApi.getSelectedRows(); // 删除行 gridApi.applyTransaction({ remove: selectedRowData }); }, []); // 或者使用更复杂的形式 gridApi.applyTransaction({ addIndex: 0, // 指定新增列的下标 // 添加的行 add: [newData], // 更新的行 update: [{ data: updatedData }], // 删除行 remove: [rowNode1, rowNode2], });
4.2 applyTransactionAsync()
- 描述: 应用一系列数据更改,包括添加、更新和删除操作。用于批量更新表格数据的方法。
- **参数:**
RowDataTransaction - **作用:**
applyTransactionAsync与applyTransaction 不同的是,applyTransactionAsync 在执行之后,数据不会立即变更,而是会在合适的时候才会更新,这样可以避免阻塞主线程,特别在大量数据的情况下,通过异步应用数据变更可以减少渲染的频率,提升性能 -
// 定义一个异步更新的函数 const onAsyncUpdate = useCallback(() => { var startMillis = new Date().getTime(); setMessage('Running Async'); var updatedCount = 0; var api = gridRef.current.api; for (var i = 0; i < 200; i++) { setTimeout(function () { // pick one index at random var index = Math.floor(Math.random() * globalRowData.length); var itemToUpdate = globalRowData[index]; var newItem = copyObject(itemToUpdate); // copy previous to current value newItem.previous = newItem.current; // then create new current value newItem.current = Math.floor(Math.random() * 100000) + 100; // 异步更新 api.applyTransactionAsync({ update: [newItem] }); }, 0); }
5. 不同的编辑模式
5.1 readOnlyEdit 只读编辑
- 描述: 光听名字,很容易迷糊,都只读了为啥还能编辑。
- 当
readOnlyEdit 设置为true 时,单元格编辑不会直接更新网格中的数据,而是触发cellEditRequest 事件 -
<AgGridReact readOnlyEdit={true} // 其他配置... />
5.2 onCellEditRequest
- 描述:
仅在 readOnlyEdit=true 时触发,当编辑后的值发生变化时触发 - 场景描述: 当编辑单元格后,需要应用程序执行特定的数据更新逻辑,而不是直接应用编辑后的值。
- 应用: 在
onCellEditRequest 事件中,可以根据编辑后的值、编辑前的值和相关数据执行自定义的数据更新逻辑。这样,可以根据业务需求实现更复杂的数据更新行为。比如说表格的协同编辑 -
onCellEditRequest(event: CellEditRequestEvent<TData>): void { // 仅在 readOnlyEdit=true 时触发,当编辑后的值发生变化时触发 const newValue = event.newValue; const oldValue = event.oldValue; const rowData = event.data; // 执行自定义逻辑... }
6. 指定唯一ID
6.1 getRowId
- 描述: 用于从数据中提取行的唯一标识符
- 作用: 这个API本身和编辑是无关的,但是选择、移动、编辑新增、更新、删除往往需要涉及到查找数据,通过
getRowId,可以更有效地跟踪和管理行的变化,特别是在大量数据的情况下,性能会更好。 -
// 定义一个自定义的 getRowId 函数 const getRowId = data => data.id; // 在 AgGridReact 中应用 getRowId <AgGridReact getRowId={getRowId} // 其他配置... /> // 指定了rowId之后,就可以根据id来进行更新和删除了 const myTransaction = { add: [ { name: 'Billy', age: 55} ], update: [ {id: '2', name: 'Bob', age: 23} ], remove: [ // {id: '5'} ] }