简体   繁体   English

GWT:可以从外部JavaScript而不是JSNI调用Java方法吗?

[英]GWT: Can Java method be called from external JavaScript instead of JSNI?

I'm trying to move most of my native JavaScript code out of JSNI methods and into scripts, and just leveraging the native JSNI methods to call those external methods. 我正在尝试将大部分原生JavaScript代码从JSNI方法转移到脚本中,并且只是利用本机JSNI方法来调用这些外部方法。

Right now I'm having difficulties with one of my click handlers. 现在我的一个点击处理程序遇到了困难。 When the user clicks a particular element, a JSNI method does some JQuery-based animation, and then calls a Java method in the callback. 当用户单击某个特定元素时,JSNI方法会执行一些基于JQuery的动画,然后在回调中调用Java方法。 A simple example is this: 一个简单的例子是这样的:

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

This code works. 这段代码有效。 It compiles and works as expected. 它编译并按预期工作。 I want to move this into an external JavaScript. 我想将其转换为外部JavaScript。 I tried the following. 我尝试了以下内容。 I put this in the external 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...
    });
}

And modified the native function like this: 并修改了这样的原生函数:

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

But is incorrect. 但是不正确。 The JavaScript file won't even load because this is not correct JavaScript. JavaScript文件甚至不会加载,因为这不是正确的JavaScript。 (Chome's dev tools give me the error message "Uncaught SyntaxError: Unexpected identifier".) (Chome的开发工具给我错误消息“Uncaught SyntaxError:Unexpected identifier”。)

Is there a way to call a Java method from an external JavaScript file, not from a JSNI method? 有没有办法从外部JavaScript文件调用Java方法, 而不是从JSNI方法调用?

I'm in GWT 2.4, if it matters. 如果重要的话,我在GWT 2.4中。

The answer is no, you cannot call Java methods explicitly from the external JavaScript function. 答案是否定的,您无法从外部JavaScript函数中显式调用Java方法。

However, you can be clever and take advantage of the fact that JavaScript allows you to pass functions themselves as parameters. 但是,您可以聪明并利用JavaScript允许您将函数本身作为参数传递的事实。

I modified my JavaScript function like so: 我修改了我的JavaScript函数:

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

And in my Java code I explicitly passed the Java method as a callback function parameter: 在我的Java代码中,我显式地将Java方法作为回调函数参数传递:

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

This way, when the JSNI method compiles, it correctly calls the doSomething() Java method, and that method call is correctly passed in its entirety to the external JavaScript function. 这样,当JSNI方法编译时,它正确调用doSomething() Java方法,并且该方法调用正确地完全传递给外部JavaScript函数。

Although you cannot make calls to Java classe's methods directly from JavaScript with vanilla GWT, gwt-exporter does a lot of the plumbing required for calling the methods of 'Java' objects from native JavaScript. 虽然你无法直接从带有vanilla GWT的JavaScript调用Java classe的方法,但是gwt-exporter在从本机JavaScript调用'Java'对象的方法时需要很多管道。

You can do things like: 你可以这样做:

Java: Java的:

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

JavaScript: JavaScript的:

MYOBJ.doSomething();

gwt-exporter works well with GWT 2.4, gwt-exporter与GWT 2.4配合得很好,

Yes, you can export your Java (GWT) methods as JavaScript functions, and you can put your Java objects into JavaScript variables. 是的,您可以将Java(GWT)方法导出为JavaScript函数,并且可以将Java对象放入JavaScript变量中。 Here's a simple example: 这是一个简单的例子:

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

Then, in JavaScript (after onModuleLoad() has been called!), you can use it easily like 然后,在JavaScript中(在调用onModuleLoad()之后!),您可以轻松地使用它

doSomething(firstCustomPanel);
doSomething(anotherCustomPanel);

Your example would now look like this: 您的示例现在看起来像这样:

jQuery("#theElement").click(function() {
    // some JQuery animation logic here...
    $wnd.jQuery("#theElement").animate({ top: "500px" }, 500, function() {
        doSomething(firstCustomPanel);
    });
    // some other code here...
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM