GWT JSNI — с Java на Javascript Назад к Java приводит к неопределенным параметрам

Я ломал голову над этим большую часть двух дней. Я прочитал документацию по JSNI здесь, а также несколько других блогов публикации в JSNI и передача переменных, таких как эта и ничто не указывает на то, что я делаю что-то не так. По сути, то, что я пытаюсь сделать, это вызвать из моего класса на стороне клиента GWT метод javascript, который я экспортирую в javascript по мере загрузки моего класса. Этот метод берет параметры из другого метода JS и сохраняет их в экземпляре класса Java, который я передал. Кажется, это работает. Но как только я ссылаюсь на эти методы в своем java-коде, они становятся неопределенными. Я считаю, что происходит то, что мой экземпляр класса Java каким-то образом теряется после завершения JS. Вот некоторый код, который поможет объяснить рабочий процесс...

У меня есть класс Java с именем ProfileWidgee. Этот класс имеет метод для установки локальных переменных для местоположения, широты и долготы. Имя этого метода...

public void handleTargetPicked(String mloc, String mlat, String mlng)  {
    loc = mloc.equalsIgnoreCase("undefined") ? "" : mloc;
    lat = mlat.equalsIgnoreCase("undefined") ? "" : mlat;
    lng = mlng.equalsIgnoreCase("undefined") ? "" : mlng;
    Window.alert("setting on js side" + loc + lat + lng);
}

Этот метод экспортируется в JS как функция с использованием метода JSNI с именем exportMyFunction...

public static native void exportMyFunction(ProfileWidgee instance)/*-{
   $wnd.handleTargetPicked = $entry(
      [email protected]::handleTargetPicked(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;));

}-*/;

Кажется, все идет хорошо. Он экспортируется, и я могу вызвать handleTargetPicked в своем JS следующим образом...

handleTargetPicked(encodeURIComponent(place.formatted_address), 
    encodeURIComponent(place.geometry.location.lat()),
    encodeURIComponent(place.geometry.location.lng()));

Все это работает, и Window.alert() отображает правильные значения. Это заставляет меня поверить, что у него есть соответствующий экземпляр моего класса и что он правильно устанавливает переменные. Однако позже, когда я вернулся в свой класс Java, я пытаюсь ссылаться на эти переменные, и они всегда возвращаются как «неопределенные».

Window.alert("reading on the java side" + pw.getLoc() + pw.getLat() + pw.getLng());

Это приводит к «неопределенному» для всех трех значений. Итак, мой большой вопрос: можно ли установить значение в вашем классе Java со стороны JS, а затем использовать это значение позже в вашем классе?


person Phil    schedule 22.09.2016    source источник
comment
Никогда не мог получить ответ на этот вопрос, поэтому в итоге я вызвал функции БД для хранения значений в базе данных, а затем вытащил их с обеих сторон.   -  person Phil    schedule 14.11.2016


Ответы (1)


Я просто столкнулся с похожей ситуацией и случайно увидел ваш пост. Я нигде не видел предложенных решений, поэтому попытался отладить его самостоятельно.

Я увидел, что переменная this указывала на окно, а не на экземпляр объекта.

Поэтому вместо того, чтобы вызывать метод напрямую, например, например. handleTargetPicked(arg1, arg2), я использовал method.call(), передавая контекст, например, например. handleTargetPicked.call(экземпляр, arg1, arg2). Такой подход решил проблему для меня. Надеюсь, это поможет.

person Denero    schedule 09.05.2017
comment
Это действительно проблема. Метод следует экспортировать как вызов функции, чтобы получить правильную привязку this: $entry(function(loc,lat,lng) { instance.@::handleTargetPicked(*)(loc,lat,lng); }) - person Thomas Broyer; 10.05.2017
comment
Я тоже застрял в этом, можете ли вы предоставить правильную подпись для того же самого. это правильно? ` public static native void exportMyFunction (экземпляр ProfileWidgee)/*-{ $wnd.handleTargetPicked = $entry( [email protected]::handleTargetPicked(Lcom/n/j/client/widgees/profile /ProfileWidgee,Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)); }-*/; ` - person Abhishek2k6; 05.06.2017
comment
или public static native void exportMyFunction(ProfileWidgee instance)/*-{ $wnd.handleTargetPicked = $entry( [email protected]::handleTargetPicked(this;Ljava/lang/String;Ljava/lang /String;Ljava/язык/String;)); - person Abhishek2k6; 05.06.2017
comment
Оба неверны. Делайте так: // Предположим, ваш метод принимает 3 параметра типа string — скажем, arg1, arg2, arg3 var methodRef = [email protected]::handleTargetPicked(Ljava/lang/String;Ljava /lang/String;Ljava/lang/String;); methodRef.call(this, arg1, arg2, arg3); - person Denero; 08.06.2017
comment
var methodRef = [email protected]::handleleTargetPicked(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;); methodRef.call(экземпляр, arg1, arg2, arg3); - person Denero; 09.06.2017