Вызов функции GWT Java из JavaScript
Я новичок в GWT и JavaScript. Есть похожие вопросы такого типа, которым я пытался следовать, но продолжаю терпеть неудачу.
У меня есть приложение GWT, мне нужно вызвать функцию Java из Javascript(в частности, при нажатии на тег href). Вот что я сделал.
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() в функции точки входа. Я продолжаю сталкиваться с различными видами исключений (нет таких исключений класса). Может кто-нибудь поправить меня?
С уважением
2 ответа
Позвольте мне объяснить немного больше об экспорте GWT в мир JS. У вас есть несколько вариантов сделать это, но я остановлюсь на трех методах.
[EDITED]
0- JsInterop: сопровождающие GWT работают над новой функцией, позволяющей легко экспортировать методы java в javascript и оборачивать объекты javascript. В 2.7.0 эта функция была очень экспериментальной, в ней отсутствовали некоторые функции, но в 2.8.0 она будет почти функциональной. Пожалуйста, ознакомьтесь с Проектной документацией и другими обсуждениями в списке рассылки.
[КОНЕЦ]
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
будет возвращать всегда двойной, и вы должны конвертировать в 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)
с вар-аргами 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
класс, который всегда возвращает число в виде двойного, или вы можете использовать JsCache
который позволяет конвертировать числа в любой другой числовой тип в Java ((JsCache)ary.get(1, Integer.class)
В качестве резюме, я бы предпочел использовать gwt-exporter в качестве первого варианта, потому что он специализируется на решении этой проблемы. В качестве второго варианта я бы использовал gquery, который является серьезным дополнением к gwt. Наконец, я бы избегал использовать рукописные jsni, когда это возможно, Javascript, как правило, является источником проблем и ошибок (думаю, что главная цель gwt - не иметь дело с js).
Вы должны рассмотреть GWT экспортер. Вы можете даже подождать, потому что GWT 2.8 должен выйти довольно скоро. Предполагалось, что он выйдет в какое-то время в начале 2015 года. 2015 год уже начался, и сейчас они демонстрируются на GWT.create, поэтому он должен выйти в любой день. Если вы не можете ждать, то можете использовать экспериментальное взаимодействие, JSNI, как указано в верхнем ответе, или GWT-экспортер. JSNI является более сложным и включает в себя много кода котельной плиты, поэтому, если вам нужно много взаимодействовать с js, я рекомендую GWT-экспортер.