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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 13:18:07