Vaadin中JS调用Java方法报错:Cannot read properties of null (reading '$server')
问题解决:Vaadin中JS调用Java @ClientCallable方法报$server为null
问题原因
你传递给executeJs的是Java端的MainView组件实例,而非该组件对应的客户端DOM元素引用。Vaadin里只有组件的客户端元素对象才会包含$server属性,用于实现JS与Java端的双向通信,直接传递Java组件实例会导致JS中拿到的对象没有$server,从而触发报错。
解决方案
1. 传递客户端元素引用给JS
修改Java代码中executeJs的参数,将this替换为this.getElement(),这样传递给JS的就是正确的客户端元素对象:
@StyleSheet("https://cdn.jsdelivr.net/npm/shepherd.js@10.0.1/dist/css/shepherd.css") @JavaScript("https://cdn.jsdelivr.net/npm/shepherd.js@10.0.1/dist/js/shepherd.min.js") @JsModule("./scripts/shepherd.js") public class MainView extends VerticalLayout { public MainView() { Button button = new Button("Click me"); button.addClickListener(c -> UI.getCurrent().getPage().executeJs("window.startTour($0)", this.getElement()); } @ClientCallable public boolean shouldUseModalOverlay() { return true; } }
2. 调整JS中的方法调用
同步修改shepherd.js中的代码,调用重命名后的Java方法(避免get这类通用名称引发冲突):
window.startTour = (element) => { let useModalOverlay = element.$server.shouldUseModalOverlay() }
额外说明
- 避免使用
get这类可能和JS内置方法或Vaadin内部方法重名的@ClientCallable方法名,改用更具语义的名称能减少潜在问题。 - Vaadin中,只有通过
getElement()获取的客户端元素对象,才具备与Java端通信的$server代理,直接传递Java组件实例无法实现双向调用。
内容的提问来源于stack exchange,提问作者Ji Lin
相关产品推荐
相关产品推荐

