You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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回调触发后编辑器未关闭

错误点说明

  1. 直接监听编辑组件的focusout事件不可靠:该事件会在点击Grid内部其他可聚焦元素时触发,且事件触发时编辑器可能处于状态锁定阶段,直接调用关闭方法不会生效
  2. 非缓冲模式下优先调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 20:54:03