Вызов функции 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-экспортер.

Другие вопросы по тегам