本文介绍了从 JavaScript 调用 GWT Java 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 GWT 和 JavaScript 的新手.我曾尝试关注此类类似的问题,但我一直失败.

I am a newcomer to GWT and JavaScript.There are similar question of this type I have tried to follow, but I keep failing.

我有一个 GWT 应用程序,我需要从 Javascript 调用 Java 函数(特别是在点击 href 标签时).以下是我所做的.

I have a GWT app, I need to call a Java function from Javascript( on the onclick of a href tag, in particular.) Following is what I have done.

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);
 }-*/;

}

在 HTML 中,

<a href="javascript:handleAnchorClick(a1,a2);">link</a>

(a1 , a2) 是我代码中的两个整数变量.我还在入口点函数中调用了 EnclosureClass.exportMyFunction().我不断遇到各种异常(没有此类异常).有人可以纠正我吗?

(a1 , a2) are two integer variables in my code.I have also called EnclosingClass.exportMyFunction() in the entry point function.I keep running into various kinds of exceptions(No Such class exception). Can someone please correct me?

问候

推荐答案

让我解释一下关于将 GWT 内容导出到 JS 世界的更多信息.您有多种选择可以做到这一点,但我将重点介绍三种方法.

Let me explain a bit more about exporting GWT stuff to the JS world. You have several options to do that, but I will focus on three methods.

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

0- JsInterop: GWT maintainers are working in a new feature to easily export java methods to javascript, and wrap javascript objects. The feature was very experimental in 2.7.0 lacking some features, but in 2.8.0 will be almost functional. Please take a look to the Design Document, and other discussions in the mailing list.

[结束]

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

1- JSNI: The first one is to write your own jsni, in this case you have to be aware about the possible mistakes you could make. Basically these mistakes are because you have to know how to deal with types. In your case if you want to get a javascript array (like you are asking in your comment below), the solution could be:

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])

请注意,JSNI 只允许您传递 primitive 类型(long 除外)和 JavaScriptObject 对象.因此,在传递 javascript 数组时,您必须像示例中那样使用 JavaScriptObject 接收它.在这种情况下,由于 javascript 仅使用数字类型,args.getNumber 将始终返回双精度值,您必须在 java 中进行转换.

Note that JSNI only allows you to pass primitive types (except long) and JavaScriptObject objects. So when passing a javascript array, you have to receive it with a JavaScriptObject like in the example. In this case, since javascript only uses a type for numbers, args.getNumber will return always a double, and you have to convert in java.

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

2- gwt-exporter For exporting large projects, or when you need to handle complex objects and classes I'd rather use 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])

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

gwt-exporter will deal with any kind of primitive types (even with long) myfunc(long[] args), with var-args myfunc(long...args), it supports method overload, and much more.

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

3- gwtquery Finally if you prefer gwtquery, you can use a technique to add function properties to any js object like 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])

使用 gquery,你可以使用 gwt JsArrayMixed 类,它总是以双精度形式返回一个数字,或者你可以使用一个 JsCache ,它允许将数字转换为任何其他数字输入 java ((JsCache)ary.get(1, Integer.class)

With gquery you can use the gwt JsArrayMixed class which always returns a number as a double, or you can use a JsCache which allows to convert numbers to any other numeric type in java ((JsCache)ary.get(1, Integer.class)

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

As a summary, I would rather use gwt-exporter as the first option because it is specialized in handling this problematic. As a second option, I would use gquery which is a serious complement to gwt. Finally, I would avoid to use hand-written jsni when possible, Javascript is normally a source of issues and mistakes (think that the main goal of gwt is not to deal with js).

这篇关于从 JavaScript 调用 GWT Java 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-03 09:10