从GWT JSNI的内部函数调用Java方法



我使用W3C Geolocation API来检索GWT web应用程序中的位置信息。地理位置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
        this.@com.test.GpsPanel::testMethod()();
        alert("Coordinates retrieved: " + lat + ";" + lng + ";" + alt);
    }
    function onPositionUpdateFailed(error) {
        alert("Some error");
    }
    if(navigator.geolocation) {
        // OK when invoked somewhere here
        this.@com.test.GpsPanel::testMethod()();
        navigator.geolocation.getCurrentPosition(onPositionUpdate, onPositionUpdateFailed);
    } else {
        alert("Geolocation is not available");
    }
}-*/;

我试图证明方法testMethod不是从内部方法onPositionUpdate调用的。更重要的是:之后不会显示警报(删除testMethod调用时会显示警报),但在日志中没有发现警告或错误。

我的问题是:如何从内部函数引用这种方法?我感觉this.不是一个正确的参考从内部函数。如果Java类不能被正确引用,那么可能的解决方法是什么?请注意,我不能向函数onPositionUpdate()传递任何其他内容,因为它是一个回调函数。

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;
        that.@com.test.GpsPanel::testMethod()();
        alert("Coordinates retrieved: " + lat + ";" + lng + ";" + alt);
    }
    // ...
}-*/;

我确信这在谷歌的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;
        instance.@com.test.GpsPanel::testMethod()();
        alert("Coordinates retrieved: " + lat + ";" + lng + ";" + alt);
    }
    // ...
}-*/;

导致相同行为的一个相关的小错误是在调用Java方法时忘记了第二对括号。第一对为了识别目的重述方法头,而第二对包含实际参数。当没有争论时,这个错误特别容易犯,例如

instance.@com.test.GpsPanel::testMethod()();

最新更新