Вызов методов Java из внутренней функции GWT JSNI

Я использую W3C Geolocation API для получения информации о местоположении в веб-приложении GWT. API геолокации построен таким образом, что функция обратного вызова вызывается сразу после получения местоположения.

Мой текущий тестовый код выглядит следующим образом:

public native void getCoordinates() /*-{
    function onPositionUpdate(position) {
        var lat = position.coords.latitude;
        var lng = position.coords.longitude;
        var alt = position.coords.altitude;

        // not OK,- doesn't get invoked, and function execution stops at this point
        [email protected]::testMethod()();

        alert("Coordinates retrieved: " + lat + ";" + lng + ";" + alt);
    }

    function onPositionUpdateFailed(error) {
        alert("Some error");
    }

    if(navigator.geolocation) {
        // OK when invoked somewhere here
        [email protected]::testMethod()();

        navigator.geolocation.getCurrentPosition(onPositionUpdate, onPositionUpdateFailed);
    } else {
        alert("Geolocation is not available");
    }
}-*/;

Я пытаюсь продемонстрировать, что метод testMethod не вызывается из внутреннего метода onPositionUpdate. Более того: никаких предупреждений после этого не отображается (оно отображается, когда вызов testMethod удаляется), но в журнале не обнаруживается никаких предупреждений или ошибок.

Мой вопрос: как я могу ссылаться на этот метод из внутренней функции? У меня такое ощущение, что this. не является правильной ссылкой из внутренних функций. Если на класс Java нельзя ссылаться правильно, то каковы возможные обходные пути? Обратите внимание, что я не могу ничего передать функции onPositionUpdate(), так как это функция обратного вызова.


person Art Licis    schedule 21.07.2012    source источник


Ответы (2)


this выходит за рамки, когда функция, определенная внутри вашего javascript в блоке JSNI, действительно выполняется.

Добавьте замыкание вокруг this:

public native void getCoordinates()
/*-{

    var that = this;

    function onPositionUpdate(position) {
        var lat = position.Wecoords.latitude;
        var lng = position.coords.longitude;
        var alt = position.coords.altitude;

        [email protected]::testMethod()();

        alert("Coordinates retrieved: " + lat + ";" + lng + ";" + alt);
    }

    // ...
}-*/;

Я был уверен, что это где-то задокументировано в документах Google JSNI, по крайней мере, в мимолетном примере, но сейчас я не могу его найти.

Это также может быть достигнуто путем передачи экземпляра в инъекцию javascript, например:

public native void getCoordinates(com.test.GpsPanel instance)
/*-{

    function onPositionUpdate(position)
    {
        var lat = position.Wecoords.latitude;
        var lng = position.coords.longitude;
        var alt = position.coords.altitude;

        [email protected]::testMethod()();

        alert("Coordinates retrieved: " + lat + ";" + lng + ";" + alt);
    }

    // ...
}-*/;
person pb2q    schedule 21.07.2012
comment
можем ли мы заменить instance на com.test.GpsPanel как [email protected]::testMethod()(); - person Piyush Srivastava; 28.11.2013

Связанная тривиальная ошибка, приводящая к такому же поведению, состоит в том, чтобы забыть вторую пару квадратных скобок при вызове методов Java. Первая пара переформулирует заголовок метода для целей идентификации, а вторая пара содержит фактические аргументы. Эту ошибку особенно легко совершить, когда нет аргументов, например.

[email protected]::testMethod()();
person Phil C    schedule 05.05.2014
comment
зачем нужна идентификация, если есть скобки? - person Alex78191; 15.06.2018