我试图将大部分原生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:意外的标识符"。)
有没有办法从外部JavaScript文件调用Java方法,不是来自JSNI方法?
我在GWT 2.4中,如果重要的话。
答案 0 :(得分: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函数。
答案 1 :(得分:4)
虽然你无法直接从带有vanilla GWT的JavaScript调用Java classe的方法, gwt-exporter执行了从本机JavaScript调用'Java'对象方法所需的大量管道。
您可以执行以下操作:
爪哇:
@ExportPackage("")
@Export("MYOBJ");
class MyClass implements Exportable {
public void doSomething();
}
JavaScript的:
MYOBJ.doSomething();
gwt-exporter适用于GWT 2.4,
答案 2 :(得分: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...
});