3

我正在尝试将我的大部分原生 JavaScript 代码从 JSNI 方法中移到脚本中,并且只是利用原生 JSNI 方法来调用这些外部方法。

现在,我的一个点击处理程序遇到了困难。当用户单击特定元素时,JSNI 方法会执行一些基于 JQuery 的动画,然后在回调中调用 Java 方法。一个简单的例子是这样的:

public native void attachClickHandler(SomeCustomPanel customPanel) /*-{
    $wnd.jQuery("#theElement").click(function() {
        // some JQuery animation logic here...
        $wnd.jQuery("#theElement").animate({ top: "500px" }, 500, function() {
            customPanel.@com.something.whatever.client.SomeCustomPanel::doSomething()();
        });
        // some other code here...
    });
}-*/;

此代码有效。它按预期编译和工作。我想把它移到外部 JavaScript 中。我尝试了以下。我把它放在外部 JavaScript 中:

function attachClickAction(customPanel) {
    $("#theElement").click(function() {
        // other stuff...
        $("#theElement").animate({ top: "500px" }, 500, function() {
            customPanel.@com.something.whatever.client.SomeCustomPanel::doSomething()();
        });
        // other stuff...
    });
}

并像这样修改了本机函数:

public native void attachClickHandler(SomeCustomPanel customPanel) /*-{
    $wnd.attachClickAction(customPanel);
}-*/;

但是是不正确的。JavaScript 文件甚至不会加载,因为这不是正确的 JavaScript。(Chome 的开发工具给了我错误信息“Uncaught SyntaxError: Unexpected identifier”。)

有没有办法从外部 JavaScript 文件调用 Java 方法,而不是从 JSNI 方法?

如果重要的话,我在 GWT 2.4 中。

4

3 回答 3

5

答案是否定的,您不能从外部 JavaScript 函数显式调用 Java 方法。

但是,您可以很聪明地利用 JavaScript 允许您将函数本身作为参数传递的事实。

我修改了我的 JavaScript 函数,如下所示:

function attachClickAction(callbackFunction) {
    $("#theElement").click(function() {
        // other stuff...
        $("#theElement").animate({ top: "500px" }, 500, callbackFunction);
    // other stuff...
    });
}

在我的 Java 代码中,我明确地将 Java 方法作为回调函数参数传递:

public native void attachClickHandler(SomeCustomPanel customPanel) /*-{
    $wnd.attachClickAction(function() {
        customPanel.@com.something.whatever.client.SomeCustomPanel::doSomething()();
    });
}-*/;

这样,当 JSNI 方法编译时,它会正确调用doSomething()Java 方法,并且该方法调用会正确地完整地传递给外部 JavaScript 函数。

于 2012-08-24T22:23:21.243 回答
4

尽管您不能使用 vanilla GWT 直接从 JavaScript 调用 Java 类的方法,但 gwt-exporter完成了从本机 JavaScript 调用“Java”对象的方法所需的大量管道。

您可以执行以下操作:

爪哇:

@ExportPackage("")
@Export("MYOBJ");
class MyClass implements Exportable {
   public void doSomething();
}

JavaScript:

MYOBJ.doSomething();

gwt-exporter 适用于 GWT 2.4,

于 2012-08-25T05:50:15.780 回答
2

是的,您可以将 Java (GWT) 方法导出为 JavaScript 函数,并且可以将 Java 对象放入 JavaScript 变量中。这是一个简单的例子:

@Override
public void onModuleLoad() {
  exportJavaMethodsToJs();

  final SomeCustomPanel firstCustomPanel = new SomeCustomPanel("first");
  exportJavaObjectToJs("firstCustomPanel", firstCustomPanel);

  final SomeCustomPanel anotherCustomPanel = new SomeCustomPanel("another");
  exportJavaObjectToJs("anotherCustomPanel", anotherCustomPanel);
}

native void exportJavaMethodsToJs() /*-{
  $wnd.doSomething = function(panel) {
    panel.@com.something.whatever.client.SomeCustomPanel::doSomething()();
  }
  // Export any methods you need in JavaScript here...
}-*/;

native void exportJavaObjectToJs(final String key, final Object object) /*-{
  $wnd[key] = object;
}-*/;

然后,在 JavaScript 中(在 onModuleLoad() 被调用之后!),您可以像这样轻松地使用它

doSomething(firstCustomPanel);
doSomething(anotherCustomPanel);

您的示例现在如下所示:

jQuery("#theElement").click(function() {
    // some JQuery animation logic here...
    $wnd.jQuery("#theElement").animate({ top: "500px" }, 500, function() {
        doSomething(firstCustomPanel);
    });
    // some other code here...
});
于 2012-08-25T09:39:38.183 回答