Vaadin Flow JavaScript 调用 Java

3
根据这个教程https://vaadin.com/blog/calling-java-from-javascript,我正在尝试从JavaScript调用Java函数,但似乎没有按预期工作。
我有一个包含按钮的视图,在其onClick处理程序上触发对Javascript函数的调用,这按预期工作。
我的问题在于,当我将getElement()传递给javascript函数时,它在达到javascript方面时是未定义的。
我的代码如下:
@JavaScript("./js/script.js")
public class RouteGraphicsView extends Div {
....
        Button b = new Button("Test Button");
        b.addClickListener(new ComponentEventListener<ClickEvent<Button>>() {

            private static final long serialVersionUID = 1L;

            @Override
            public void onComponentEvent(final ClickEvent<Button> event) {
                UI.getCurrent().getPage().executeJs("greet($0, $1)", "test name", UI.getCurrent().getElement());
            }
        });
....
}

上述调用到达了 script.js 文件,其代码如下:
window.greet = function greet(name, element) {
    console.log("Hello, I am greeting you, " + name);
    
    try {
        console.log("Element ", element);
        console.log("Logging 1", element.$server);
    } catch (e) {
        console.log(e);
    }
}

上面greet函数展示的输出是:
Hello, I am greeting you, test name
vaadin-bundle-62ac8b…b56c6.cache.js:4813 Element  
vaadin-bundle-62ac8b…b56c6.cache.js:4813 Logging 1 undefined

由于元素$server未定义,我无法调用我的greet函数,该函数在视图中使用@ClientCallable进行了注释。
@ClientCallable
public void greet(final String name) {
    System.out.println("Called from JavaScript: " + name + " \n\n\n");
}

我尝试了各种调用script.js的方法,例如使用按钮元素来调用executeJs函数或将按钮元素(b.getElement())作为参数传递给函数,但都没有成功。
我做错了什么?
1个回答

2
您正在对作为UI.getCurrent().getElement()传递的元素执行element.$server操作。这对应于UI实例,而不是具有@ClientCallable方法的RouteGraphicsView类的实例(我假设)。使用按钮也会出现同样的问题。
您应该传递视图的实例,在您的情况下需要编写为RouteGraphicsView.this,因为常规的this引用单击侦听器的方式。

首先感谢您的回答,Leif。 现在,为了澄清一些事情,是的,我的@ClientCallable位于RouteGraphicsView类中。 我正在运行的Vaadin版本是14.7.0(如果这有任何兴趣的话)。 其次,在从Java到JavaScript转换方面,教程所说的做法与实际有所不同。教程中说我应该使用getElement().executeJavaScript来调用.js文件中的函数。当我尝试这样做时,javascript方面什么也没有发生。只有当我执行UI.getCurrent().getElement().executeJs时,事情开始变得复杂起来。 - Sergiu
зҺ°еңЁпјҢжҲ‘е°қиҜ•дәҶдҪ зҡ„е»ә议并е°ҶUI.getCurrent().getPage().executeJs("greet($0, $1)", "test name", UI.getCurrent().getElement());жӣҙж”№дёәUI.getCurrent().getPage().executeJs("greet($0, $1)", "test name", RouteGraphicsView.this);дҪҶжҳҜжІЎжңүд»»дҪ•ж•ҲжһңгҖӮеҰӮжһңдҪ жңүе…¶д»–е»әи®®пјҢжҲ‘еҫҲд№җж„Ҹеҗ¬еҸ–гҖӮ - Sergiu
这里有一个与我遇到的相似的帖子:https://stackoverflow.com/questions/69192087/element-server-is-undefined-when-passing-data-from-java-to-javascript-in-vaadin - Sergiu
我通过在类中添加@Route和在构造函数中添加add(b);将不同的代码片段组装成一个整体。通过这些小调整,当我将RouteGraphicsView.this作为第二个参数传递给executeJs时,示例对我有效。这不应该有任何影响,但我使用了不同的Vaadin版本。您可以尝试使用最新的14.x版本,即14.8.20。 - Leif Åstrand
如果 getElement().executeJavaScript 没有任何影响,那么问题似乎是您的组件没有正确附加。不过我不知道这是什么意思,因为按钮也会消失(尽管您没有显示添加按钮的代码,所以我不知道应该如何添加)。 - Leif Åstrand
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接