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

ZK 10中doAfterCompose()调用Messagebox.show()致页面渲染停滞问题

ZK 10升级后Messagebox弹出时后台页面未渲染的解决方案

问题背景

从ZK 8.5.2.1升级至适配Jakarta的最新ZK 10热修复版本后,在doAfterCompose()方法中弹出模态Messagebox时出现异常:旧版本中弹出Messagebox的同时,后台页面会完整渲染;但ZK 10中,尽管Java代码仍在执行,Messagebox背后的页面却未完成渲染。禁用Messagebox后页面可正常渲染,且未使用已废弃的事件线程处理机制。

相关代码片段:

// ...doAfterCompose() - check if its read or unread and offer user to mark as read
if (!TrueFalseConverter.instance().nvlFrom(entity.getLPrectena())) {
    Messagebox.show(Labels.getLabel("diaries.make.msg.question.order.set_read.text"), Labels.getLabel("diaries.make.msg.question.order.set_read.title"), Messagebox.YES | Messagebox.NO, Messagebox.QUESTION, new SerializableEventListener<Event>() {

        @Override
        public void onEvent(Event event) throws Exception {
            if (Messagebox.ON_YES.equals(event.getName())) {
                entity.setLPrectena(TrueFalseConverter.instance().to(Boolean.TRUE));
                app.r.ovdenObjednavkyRepository.store(entity);
            }
        }
    });
}
// ...continue with components creation and render the page

问题分析

ZK 10对UI渲染流程做了调整:在组件初始化阶段(如doAfterCompose)调用Messagebox.show()时,模态对话框的渲染会优先抢占响应资源,导致后续的组件创建和页面渲染逻辑虽执行,但对应的UI更新被延迟至Messagebox关闭后才触发。而ZK 8.5的处理逻辑是先完成页面基础渲染,再弹出Messagebox。

解决方案

要恢复旧版本的页面渲染行为,核心思路是先完成页面渲染,再异步弹出Messagebox,以下是两种可行方案:

方案1:使用Clients.defer()延迟弹出

利用ZK的Clients.defer()方法,将Messagebox的弹出逻辑延迟到当前页面渲染周期完成后执行,确保页面先完成渲染再弹出对话框:

// ...doAfterCompose() - check if its read or unread and offer user to mark as read
if (!TrueFalseConverter.instance().nvlFrom(entity.getLPrectena())) {
    // 延迟到页面渲染完成后弹出Messagebox
    Clients.defer(new Runnable() {
        @Override
        public void run() {
            Messagebox.show(Labels.getLabel("diaries.make.msg.question.order.set_read.text"), 
                           Labels.getLabel("diaries.make.msg.question.order.set_read.title"), 
                           Messagebox.YES | Messagebox.NO, 
                           Messagebox.QUESTION, 
                           new SerializableEventListener<Event>() {

                @Override
                public void onEvent(Event event) throws Exception {
                    if (Messagebox.ON_YES.equals(event.getName())) {
                        entity.setLPrectena(TrueFalseConverter.instance().to(Boolean.TRUE));
                        app.r.ovdenObjednavkyRepository.store(entity);
                    }
                }
            });
        }
    });
}
// ...continue with components creation and render the page

方案2:使用EventQueues.schedule()异步执行

通过ZK事件队列调度,将Messagebox的弹出放在当前渲染周期之后的异步任务中:

// ...doAfterCompose() - check if its read or unread and offer user to mark as read
if (!TrueFalseConverter.instance().nvlFrom(entity.getLPrectena())) {
    EventQueues.lookup(EventQueues.APPLICATION, EventQueues.DESKTOP, true)
               .schedule(new EventListener<Event>() {
                   @Override
                   public void onEvent(Event event) throws Exception {
                       Messagebox.show(Labels.getLabel("diaries.make.msg.question.order.set_read.text"), 
                                      Labels.getLabel("diaries.make.msg.question.order.set_read.title"), 
                                      Messagebox.YES | Messagebox.NO, 
                                      Messagebox.QUESTION, 
                                      new SerializableEventListener<Event>() {

                           @Override
                           public void onEvent(Event event) throws Exception {
                               if (Messagebox.ON_YES.equals(event.getName())) {
                                   entity.setLPrectena(TrueFalseConverter.instance().to(Boolean.TRUE));
                                   app.r.ovdenObjednavkyRepository.store(entity);
                               }
                           }
                       });
                   }
               });
}
// ...continue with components creation and render the page

原理说明

两种方案均通过延迟Messagebox的弹出时机,让页面先完成当前渲染周期内的组件创建与UI渲染,再触发模态对话框,从而实现与ZK 8.5一致的效果:页面完整渲染后再弹出Messagebox,用户可正常看到后台页面内容。

内容的提问来源于stack exchange,提问作者Worsik

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:22:36