Vaadin 14非缓冲Grid编辑器点击保存后无法关闭问题求助
根本原因
- 执行顺序错误:现有代码先执行数据保存逻辑,再触发编辑器关闭。Vaadin 14 的unbuffered Grid编辑器处于修改后的脏状态时,提前操作绑定的数据源会导致前后端编辑器状态脱节,服务端标记编辑器已关闭,但前端未收到移除编辑器DOM的指令。
- 未提交编辑器脏数据直接调用关闭接口:unbuffered模式下编辑器内容修改后未主动触发提交时,closeEditor()仅更新服务端状态,不会同步前端UI变更。
- 数据源类型限制:你使用
Map作为Grid的绑定数据源,普通Map不具备属性变更观测能力,编辑器状态变更后无法自动触发Grid行刷新。 - 前端焦点问题:点击保存按钮时编辑器内的输入组件仍持有焦点,Vaadin 14 该场景下存在编辑器关闭的状态同步缺陷。
最优解决方案
第一步:调整方法执行顺序
先关闭编辑器提交修改,再执行数据持久化逻辑,避免状态脱节。
第二步:优化closeEditors实现
关闭编辑器前先提交当前修改,关闭后主动刷新编辑中的行,触发前端重绘自然移除编辑器:
private void closeEditors() { // 处理第一个网格 if (tab1.getEditor().isOpen()) { // 提交当前编辑器内的修改 tab1.getEditor().save(); tab1.getEditor().closeEditor(); // 刷新对应行,触发前端重绘 Object editedItem1 = tab1.getEditor().getItem(); if (editedItem1 != null) { tab1.getDataProvider().refreshItem(editedItem1); } } // 处理第二个网格 if (tab2.getEditor().isOpen()) { tab2.getEditor().save(); tab2.getEditor().closeEditor(); Object editedItem2 = tab2.getEditor().getItem(); if (editedItem2 != null) { tab2.getDataProvider().refreshItem(editedItem2); } } }
第三步:修正saveData方法执行顺序
public void saveData() { // 先关闭编辑器提交所有修改 closeEditors(); // 再执行数据保存逻辑 saveDataFromTab1(); saveDataFromTab2(); try { ServicesProxyImpl.getInstance().updateInBD(someObject); saveButton.setEnabled(false); cancelButton.setEnabled(false); Dialog dialog = VaadinComponentUtils.generateDialog(Constantes.MSG_SAVE_OK); dialog.open(); } catch (JAXBException e) { e.printStackTrace(); Dialog dialog = VaadinComponentUtils.generateDialog(Constantes.MSG_SAVE_KO); dialog.open(); } }
额外注意点
- 你之前的临时方案每次调用
closeEditors都会新增关闭监听器,会导致监听器重复注册、resetGrids多次执行,长期运行会引发内存泄漏和性能问题,建议废弃。 - 如果仍有偶发的编辑器未关闭问题,可以给Grid配置唯一键生成器,确保行刷新时能准确定位对应DOM:
grid.setKeyGenerator(item -> 你的唯一标识生成逻辑)。 - 条件允许的话可以将Map类型数据源替换为Vaadin的
ObservableMap,支持属性变更自动通知Grid刷新。
内容的提问来源于stack exchange,提问作者Xragg
相关产品推荐
相关产品推荐

