2012-08-24 90 views
3

我试图将大部分原生JavaScript代码从JSNI方法中移出并转换为脚本,并且只是利用本地JSNI方法来调用这些外部方法。GWT:可以从外部JavaScript代替JSNI调用Java方法吗?

现在我遇到了一个点击处理程序的问题。当用户点击某个元素时,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() { 
      [email protected]::doSomething()(); 
     }); 
     // some other code here... 
    }); 
}-*/; 

此代码的工作原理。它按预期进行编译和工作。我想将其移入外部JavaScript中。我尝试了以下。我把这个在外部JavaScript:

function attachClickAction(customPanel) { 
    $("#theElement").click(function() { 
     // other stuff... 
     $("#theElement").animate({ top: "500px" }, 500, function() { 
      [email protected]::doSomething()(); 
     }); 
     // other stuff... 
    }); 
} 

而修改这样的原生功能:

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

但不正确。 JavaScript文件甚至不会加载,因为这是不正确的JavaScript。 (丁目的开发工具给我的错误消息“未捕获的SyntaxError:意外的标识符”。)

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

我在GWT 2.4中,如果它很重要。

回答

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() { 
     [email protected]::doSomething()(); 
    }); 
}-*/; 

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

+2

注意:您应该使用'$ entry()'调用'customPanel ... doSomething()()'。 –

+0

@avasopht - 为什么?我从来没有见过这样的构造。你可以解释吗? –

+3

它围绕某些try/catch语句进行调用,以避免GWT/javascript中的Java代码异常将达到纯JavaScript代码空间。 –

4

虽然您不能直接从JavaScript与香草GWT调用Java classe的方法,但是 gwt-exporter执行了很多从原生JavaScript调用“Java”对象方法所需的工具。

你可以做这样的事情:

的Java:

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

的JavaScript:

MYOBJ.doSomething(); 

GWT-出口与GWT 2.4效果很好,

+0

不幸的是,我无法添加外部依赖项,但是您提出了建议。 –

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) { 
    [email protected]::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... 
});