从JavaScript调用GWT Java函数

fro*_*odo 16 gwt jsni gwtquery gwt-exporter

我是GWT和JavaScript的新手.我试图遵循这种类型的类似问题,但我一直都在失败.

我有一个GWT应用程序,我需要从Javascript调用Java函数(尤其是在href标签的onclick上.)以下是我所做的.

public class JSNITest {

 public static void handleAnchorClick(int a , int b) {
   Window.alert("Current row and Column is " + a + "  " + b);
 }

 public static native void exportMyFunction()/*-{
    $wnd.handleAnchorClick = function(param1,param2){
        @company.package.class.JSNITest::handleAnchorClick(*)(param1,param2);
 }-*/;

}
Run Code Online (Sandbox Code Playgroud)

在HTML中,

<a href="javascript:handleAnchorClick(a1,a2);">link</a> 
Run Code Online (Sandbox Code Playgroud)

(a1 , a2)是我的代码中的两个整数变量.我还在入口点函数中调用了EnclosingClass.exportMyFunction().我一直遇到各种异常(No Such class exception).有人可以纠正我吗?

问候

Man*_*ino 29

让我解释一下将GWT东西导出到JS世界的更多信息.你有几个选择,但我将专注于三种方法.

[EDITED]

0- JsInterop:GWT维护者正在开发一个新功能,可以轻松地将java方法导出到javascript,并包装javascript对象.该功能在2.7.0中非常具有实验性,缺少一些功能,但在2.8.0中几乎可以正常运行.请查看设计文档以及邮件列表中的其他讨论.

[结束]

1- JSNI:第一个是编写自己的jsni,在这种情况下,你必须要知道你可能犯的错误.基本上这些错误是因为你必须知道如何处理类型.在你的情况下,如果你想获得一个javascript数组(就像你在下面的评论中提到的那样),解决方案可能是:

public static native void exportMyFunction()/*-{
  $wnd.handleAnchorClick = @company.package.class.JSNITest::handleAnchorClick(*);
}-*/;

public static void handleAnchorClick(JsArrayMixed args) {
  Window.alert("Current row and Column is " +
                args.getNumber(0) + "  " + args.getNumber(1));
}

public void onModuleLoad() {
  exportMyFunction();
}

//javascript code
window.handleAnchorClick([1,2])
Run Code Online (Sandbox Code Playgroud)

请注意,JSNI仅允许您传递primitive类型(long除外)和JavaScriptObject对象.因此,当传递javascript数组时,您必须JavaScriptObject在示例中使用类似的方式接收它.在这种情况下,由于javascript仅使用数字类型,args.getNumber将始终返回double,并且您必须在java中进行转换.

2- gwt-exporter对于导出大型项目,或者当您需要处理复杂的对象和类时,我宁愿使用gwt-exporter

static class MyClass implements Exportable {
  @Export("$wnd.handleAnchorClick")
  public static void handleAnchorClick(double[] args) {
    Window.alert("Current row and Column is " +args[0] + "  " + args[1]);
  }
}

public void onModuleLoad() {
  GWT.create(MyClass.class);
}

//javascript code
window.handleAnchorClick([1,2])
Run Code Online (Sandbox Code Playgroud)

gwt-exporter将处理任何类型的原始类型(即使很长)myfunc(long[] args),使用var-args myfunc(long...args),它支持方法重载等等.

3- gwtquery最后如果您更喜欢gwtquery,您可以使用一种技术将函数属性添加到任何js对象中window

// The GQuery Properties object is able to wrap a java Function object
// into an js property.
Properties wnd = window.cast();
wnd.setFunction("handleAnchorClick", new Function() {
  public void f() {
    // Get the js arguments[] array
    JsArrayMixed args = arguments(0);
    // Get the first element of the arguments[] array
    JsArrayMixed ary = args.getObject(0);

    Window.alert("Current row and Column is " +
                  ary.getNumber(0) + "  " + ary.getNumber(1));
  }
});

//javascript code
window.handleAnchorClick([1,2])
Run Code Online (Sandbox Code Playgroud)

使用gquery,你可以使用gwt JsArrayMixed类,它总是返回一个数字作为double,或者你可以使用一个JsCache允许将数字转换为java中的任何其他数字类型((JsCache)ary.get(1, Integer.class)

作为总结,我宁愿使用gwt-exporter作为第一选择,因为它专门处理这个问题.作为第二种选择,我会使用gquery,它是gwt的一个重要补充.最后,我会避免在可能的情况下使用手写的jsni,Javascript通常是问题和错误的来源(认为gwt的主要目标不是处理js).