Ag Grid(Vue.js)单元格不可见时如何编程开启行编辑模式
Ag Grid + Vue.js 单元格不可见时编程开启行编辑模式
问题现象
- 表格列数过多时,横向滚动到非初始列区域后,编程调用编辑API无法让指定行进入全行行编辑模式,无报错无响应
- 页面初始加载未滚动时,相同编辑逻辑可正常生效
- 问题根因:Ag Grid默认开启列虚拟滚动,移出可视区域的列会被移除出DOM,此时如果调用
startEditingCell传入的列key对应列不在可视DOM中,方法会静默失败,无法启动编辑 - 需求要求:触发编辑时不需要强制滚动到目标单元格、不需要聚焦不可见单元格,直接让整行进入编辑状态
附复现代码:
import 'ag-grid-community/dist/styles/ag-grid.css'; import 'ag-grid-community/dist/styles/ag-theme-alpine.css'; import 'ag-grid-enterprise'; import { AgGridVue } from 'ag-grid-vue'; import Vue from 'vue'; const VueExample = { template: ` <div style="height: 100%"> <div class="example-wrapper"> <div style="margin-bottom: 5px;"> <button style="font-size: 12px" v-on:click="onBtStartEditing()">Start Editing Line 2</button> <button style="font-size: 12px" v-on:click="onBtStopEditing()">Stop Editing</button> </div> <ag-grid-vue style="width: 100%; height: 100%;" class="ag-theme-alpine" :columnDefs="columnDefs" @grid-ready="onGridReady" :defaultColDef="defaultColDef" :editType="editType" :rowData="rowData" @cell-value-changed="onCellValueChanged" @row-value-changed="onRowValueChanged"></ag-grid-vue> </div> </div> `, components: { 'ag-grid-vue': AgGridVue, }, data: function () { return { columnDefs: [ { field: 'make', cellEditor: 'agSelectCellEditor', cellEditorParams: { values: ['Porsche', 'Toyota', 'Ford', 'AAA', 'BBB', 'CCC'], }, }, { field: 'model' }, { field: 'field4', headerName: 'Read Only', editable: true }, { field: 'price', cellEditor: NumericCellEditor }, { headerName: 'Suppress Navigable', field: 'field5', suppressNavigable: true, minWidth: 200, }, { headerName: 'Read Only', field: 'field6', editable: true }, ], gridApi: null, columnApi: null, defaultColDef: { flex: 1, editable: true, }, editType: null, rowData: null, }; }, created() { this.editType = 'fullRow'; this.rowData = getRowData(); for(let i = 0; i < 1000; ++i) { this.columnDefs.push({ headerName: 'Read Only', field: 'field6', editable: true }); } }, methods: { onCellValueChanged(event) { console.log( 'onCellValueChanged: ' + event.colDef.field + ' = ' + event.newValue ); }, onRowValueChanged(event) { var data = event.data; console.log( 'onRowValueChanged: (' + data.make + ', ' + data.model + ', ' + data.price + ', ' + data.field5 + ')' ); }, onBtStopEditing() { this.gridApi.stopEditing(); }, // 原有问题逻辑 onBtStartEditing() { this.gridApi.setFocusedCell(1, 'make'); this.gridApi.startEditingCell({ rowIndex: 1, colKey: 'make', }); }, onGridReady(params) { this.gridApi = params.api; this.gridColumnApi = params.columnApi; }, }, }; window.getRowData = function getRowData() { var rowData = []; for (var i = 0; i < 10; i++) { rowData.push({ make: 'Toyota', model: 'Celica', price: 35000 + i * 1000, field4: 'Sample XX', field5: 'Sample 22', field6: 'Sample 23', }); rowData.push({ make: 'Ford', model: 'Mondeo', price: 32000 + i * 1000, field4: 'Sample YY', field5: 'Sample 24', field6: 'Sample 25', }); rowData.push({ make: 'Porsche', model: 'Boxster', price: 72000 + i * 1000, field4: 'Sample ZZ', field5: 'Sample 26', field6: 'Sample 27', }); } return rowData; }; new Vue({ el: '#app', components: { 'my-component': VueExample, }, });
实现方案
全行行编辑模式下,只要用任意一个当前处于可视区域的可编辑列作为锚点调用startEditingCell,整行就会正常进入编辑状态,不需要滚动表格、不需要聚焦到不可见的指定列。
修改原有onBtStartEditing方法即可:
onBtStartEditing() { const targetRowIndex = 1; const allColumns = this.gridColumnApi.getAllColumns(); // 动态查找当前第一个可视的可编辑列作为编辑锚点 let anchorColKey = null; for (const col of allColumns) { const colDef = col.getColDef(); if (col.isVisible() && colDef.editable !== false) { anchorColKey = col.getColId(); break; } } if (!anchorColKey) return; // 启动行编辑,不需要强制聚焦、不需要滚动 this.gridApi.startEditingCell({ rowIndex: targetRowIndex, colKey: anchorColKey, preventNavOnEdit: true // 禁止编辑时自动滚动到锚点单元格,完全保留当前滚动位置 }); }
方案说明
- 完全匹配需求:触发编辑时不会自动滚动表格,不会强制聚焦到非可视区单元格,当前视口内的行单元格会直接进入编辑状态
- 原有事件逻辑不受影响:
cellValueChanged、rowValueChanged等编辑相关事件触发逻辑和默认行为完全一致 - 兼容虚拟滚动场景:无论横向滚动到表格哪个位置,都会自动取当前可见列作为锚点,不会出现编辑失效问题
内容的提问来源于stack exchange,提问作者manymanymore
相关产品推荐
相关产品推荐

