Vaadin视图中无法调用@JavaScript导入的JS函数
解决Vaadin中
printWhenLoaded未定义的问题 问题原因
你的推测完全正确——@JavaScript注解引入的脚本是异步加载的,onAttach方法触发时,浏览器还没完成该JS文件的加载与解析,直接调用全局函数自然会提示未定义。
解决方案
方法1:监听脚本加载完成后执行逻辑
改用Page.addJavaScript方法加载脚本,通过回调确保脚本加载完成后再调用打印函数,这是最直接可靠的方式:
@Route() public class PrintableView extends BaseView { @Override public void setParameter(BeforeEvent event, @OptionalParameter String parameter) { super.setParameter(event, parameter); } @Override protected void onAttach(AttachEvent attachEvent) { UI.getCurrent().getPage() .addJavaScript("scripts/print.js") .then(() -> UI.getCurrent().getPage().executeJs("printWhenLoaded($0);", ".layout")); } }
方法2:前端主动通知后端脚本就绪
让JS脚本加载完成后主动触发后端方法,再执行打印逻辑,更贴合Vaadin的前后端通信机制:
- 修改
print.js,添加加载完成后的通知逻辑:
function printWhenLoaded(selector) { setTimeout(function () { var e = document.querySelector(selector); if(e && e.innerHTML.length) { window.print(); window.close(); } else printWhenLoaded(selector) }, 200) }; // 脚本加载完成后通知后端 document.addEventListener('DOMContentLoaded', function() { if (window.Vaadin?.getCurrent()) { window.Vaadin.getCurrent().$server.onPrintScriptReady(); } });
- 在
PrintableView中添加可被前端调用的方法:
@Route() @JavaScript(value="scripts/print.js") public class PrintableView extends BaseView { @Override public void setParameter(BeforeEvent event, @OptionalParameter String parameter) { super.setParameter(event, parameter); } @ClientCallable public void onPrintScriptReady() { UI.getCurrent().getPage().executeJs("printWhenLoaded($0);", ".layout"); } }
方法3:前端轮询检查函数是否可用
如果想保留原有@JavaScript注解的方式,可以在前端增加轮询逻辑,直到函数可用再执行:
@Override protected void onAttach(AttachEvent attachEvent) { UI.getCurrent().getPage().executeJs(""" function checkAndRun() { if (typeof printWhenLoaded === 'function') { printWhenLoaded($0); } else { setTimeout(checkAndRun, 100); } } checkAndRun($0); """, ".layout"); }
内容的提问来源于stack exchange,提问作者The Shoe Shiner
相关产品推荐
相关产品推荐

