Vaadin14非缓冲模式下嵌套于CRUD的Grid编辑器无法正常退出问题
Vaadin14嵌套在CRUD内的Grid编辑器Esc失效/点击外部无法关闭解决方案
问题1:Esc键触发CRUD丢弃弹窗而非关闭Grid编辑器
该问题由键盘事件向上冒泡到上层CRUD组件触发了其自带的Esc快捷键逻辑导致,不需要修改event.code判断规则,只需在监听器中阻止事件冒泡和默认行为即可,修改后代码如下:
textField.getElement().addEventListener("keydown", e -> editor.cancel()) // 过滤Esc键的同时阻止事件向上传递到CRUD组件 .setFilter("if (event.code === 'Escape') {event.stopPropagation();event.preventDefault();return true;} return false;");
注:高版本JDK可将过滤条件改为文本块格式提升可读性
问题2:点击编辑单元格外部无响应、focusout回调触发后编辑器未关闭
错误点说明
- 直接监听编辑组件的
focusout事件不可靠:该事件会在点击Grid内部其他可聚焦元素时触发,且事件触发时编辑器可能处于状态锁定阶段,直接调用关闭方法不会生效 - 非缓冲模式下优先调用
editor.cancel()而非editor.close():后者仅适用于缓冲编辑模式,不会回滚未提交的临时输入,部分场景下会出现编辑器状态不更新的问题
正确实现点击外部关闭逻辑
给当前UI注册全局点击监听器,编辑器打开时判断点击目标是否在Grid编辑器外部,再执行关闭操作:
// Grid初始化阶段添加该逻辑 editor.addOpenListener(openEvent -> { // 注册全局点击监听 Registration clickRegistration = UI.getCurrent().addListener(ClickEvent.class, event -> { if (!editor.isOpen()) { return; } // 判断点击目标是否不在Grid组件内部 boolean isClickOutside = event.getSource() instanceof Component target && !target.getElement().compareDocumentPosition(grid.getElement()).contains(Node.DocumentPosition.CONTAINED_BY); if (isClickOutside) { editor.cancel(); } }); // 编辑器关闭时移除监听避免内存泄漏 editor.addCloseListener(closeEvent -> clickRegistration.remove()); });
如果需要保留focusout回调兼容场景,可修改回调逻辑为异步执行确保编辑器状态正常更新:
textField.getElement().addEventListener("focusout", e -> { if (editor.isOpen()) { UI.getCurrent().access(() -> editor.cancel()); } });
内容的提问来源于stack exchange,提问作者Sergiu
相关产品推荐
相关产品推荐

