我是GWT和JavaScript的新手。 我试图遵循这种类型的类似问题,但我一直都在失败。
我有一个GWT应用程序,我需要从Javascript调用Java函数(尤其是在href标签的onclick上。)以下是我所做的。
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)
是我代码中的两个整数变量。
我还在入口点函数中调用了EnclosingClass.exportMyFunction()。
我一直遇到各种异常(No Such class exception)。有人可以纠正我吗?
此致
答案 0 :(得分:29)
让我解释一下将GWT内容导出到JS世界的更多内容。你有几个选择,但我会关注三种方法。
[EDITED]
0- JsInterop :GWT维护人员正在开发一项新功能,可以轻松地将java方法导出到javascript,并包装javascript对象。该功能在2.7.0中非常具有实验性,缺少一些功能,但在2.8.0中几乎可以正常运行。请查看邮件列表中的Design Document和其他discussions。
[END]
1- JSNI :第一个是编写自己的jsni,在这种情况下,你必须要知道你可能犯的错误。基本上这些错误是因为你必须知道如何处理类型。在你的情况下,如果你想获得一个javascript数组(就像你在下面的评论中提到的那样),解决方案可能是:
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
类型(长除外)和JavaScriptObject
对象。因此,当传递javascript数组时,您必须使用示例中的JavaScriptObject
接收它。在这种情况下,由于javascript仅使用数字类型,args.getNumber
将始终返回double,并且您必须在java中进行转换。
2- gwt-exporter 为了导出大型项目,或者当您需要处理复杂的对象和类时,我宁愿使用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将处理任何类型的原始类型(即使是很长的)myfunc(long[] args)
,var-args myfunc(long...args)
,它支持方法重载等等。
3- gwtquery 最后,如果您更喜欢gwtquery,您可以使用一种技术将函数属性添加到任何js对象,如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
类,它始终将数字作为double返回,或者您可以使用JsCache
允许将数字转换为java {{1中的任何其他数字类型}}
总结一下,我宁愿使用 gwt-exporter 作为第一个选项,因为它专门处理这个问题。作为第二种选择,我会使用 gquery ,这是gwt的一个重要补充。最后,我会尽可能避免使用手写 jsni ,Javascript通常是问题和错误的来源(认为gwt的主要目标不是处理js)。
答案 1 :(得分:1)
你应该考虑GWT出口商。您甚至可以考虑等待,因为GWT 2.8很快就会问世。它应该会在2015年的乞讨期间出现。2015年已经开始,他们现在正在GWT.create展示,所以它现在应该出现在任何一天。如果你不能等待那么你可以使用实验性的互操作,JSNI就像最热门的回答所说的那样或GWT出口商。 JSNI更复杂,涉及很多锅炉板代码,所以如果你需要做很多js互操作,我推荐GWT-exporter。