# ag-Grid学习笔记:编辑功能相关参数和 API 函数详解(四)

1,694 阅读7分钟

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"
      // 其他配置...
    />
    
  • image转存失败,建议直接上传图片文件

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'}
          ]
     }