1

我目前正在为 Google Map API GeoCoding 构建一个简单的示例应用程序,并偶然发现了 javascript 的问题。

geocodeRequest 方法应将其结果值分配给变量 this.tempResult。但是,当我尝试在 Listener 中打印它时,该变量为空。

控制台的输出是:

  • 听众:空
  • geoCodeRequest:对象

打印输出的顺序似乎意味着 Listener 中的代码在 geoCodeRequest 方法设法分配 this.tempResult 变量之前提前运行。

有解决方案吗?

$JSKK.Class.create
(
    {
        $namespace      :'application',
        $name           :'GeoCoder'
    }
)
(
    {
    },
    {
        service :null,
        main    :null,
        geoCodeInput: null,
        geoCodeButton: null,
        reverseGeoCodeButton: null,
        reverseGeoCodeActive: null,
        callback :null,
        reverseCallback:null,
        tempResult: null,


        init: function(main, callback, reverseCallback)
        {
            this.main = main;
            this.callback = callback;
            this.reverseCallback = reverseCallback;

            this.service = new google.maps.Geocoder();

            this.geoCodeInput = $('#toolPannel div[data-resource=locator] input[data-action=input]');
            this.geoCodeButton = $('#toolPannel div[data-resource=locator] input[data-action=geocode]');

            this.reverseGeoCodeButton = $('#toolPannel div[data-resource=locator] input[data-action=reversegeocode]');
            this.reverseGeoCodeActive = false;

            this.createListener();
        },


        geoCodeRequest: function(request)
        {
            this.service.geocode
            (
                request,
                function (result,status)
                {
                    //console.debug(arguments);
                    if (status== google.maps.GeocoderStatus.OK)
                    {
                        this.tempResult = result[0];
                        console.debug(this.tempResult);
                    }
                    else
                    {
                        alert ('GeoCoder request failed!');
                    }
                }.bind(this)
            );
        },

        createListener: function()
        {
            this.geoCodeButton.click(function()
                {
                    this.geoCodeRequest
                    (
                        {
                            address: this.geoCodeInput.val()
                        }
                    );
                    this.callback(this.tempResult);
                }.bind(this)    //Bind here
            );

            this.reverseGeoCodeButton.click(function()
                {
                    if (!this.reverseGeoCodeActive)
                    {
                        this.main.map.setOptions({draggableCursor:'crosshair'});
                        this.reverseGeoCodeActive=true;
                    }
                    else if(this.reverseGeoCodeActive)
                    {
                        this.main.map.setOptions({draggableCursor:'hand'});
                        this.reverseGeoCodeActive=false;
                    }
                }.bind(this)
            );

            google.maps.event.addListener
            (
                this.main.map,
                'click',
                function (event)
                {
                    if (this.reverseGeoCodeActive)
                    {
                        this.geoCodeRequest
                        (
                            {
                                location: event.latLng
                            }
                        );
                        console.debug(this.tempResult);
                        this.reverseCallback(this.tempResult);
                    }
                }.bind(this)
            );
        }
    }
);
4

1 回答 1

0

问题是这段代码:

geoCodeRequest: function( request ) {
    this.service.geocode( request, function( result, status ) {
        if (status == google.maps.GeocoderStatus.OK) {
            this.tempResult = result[0];
            console.debug( this.tempResult );
        } else {
            alert( 'GeoCoder request failed!' );
        }
    }.bind(this) );
},

this.geoCodeButton.click( function() {
    this.geoCodeRequest({
        address: this.geoCodeInput.val()
    });
    this.callback( this.tempResult );
}.bind(this) );

(抱歉,我冒昧地重新格式化,以便更好地遵循逻辑。请随意转换回您自己的风格。)

您正试图this.callback()在地理编码结果从服务器返回之前调用。那是行不通的。您需要在地理编码器使用的回调中处理地理编码结果。

您已经在方法中为地理编码器提供了一个回调geoCodeRequest(),因此您可以做的是向您的点击处理程序添加一个回调,并从geoCodeRequest(). 你可以这样做:

geoCodeRequest: function( request ) {
    this.service.geocode( request, function( result, status ) {
        if (status == google.maps.GeocoderStatus.OK) {
            request.success( result[0] );
        } else {
            request.failure( status );
        }
    }.bind(this) );
},

this.geoCodeButton.click( function() {
    this.geoCodeRequest({
        address: this.geoCodeInput.val(),
        success: function( result ) {
            console.debug( result );
            this.callback( result );
        },
        failure: function( status ) {
            alert( 'GeoCoder request failed!' );
        }
    });
}.bind(this) );

请注意,我还添加了一个失败回调来处理错误情况。

处理程序有相同的reverseGeoCodeButton.click()问题,可以用相同的解决方案修复。

This is close to your original approach, but I have to wonder if the code could be simplified. Do you need these multiple levels of code? In any case, wherever you're dealing with an asynchronous result like what the geocoder gives you, you do have to handle that inside the appropriate callback instead of after the geocoder (or any asynchronous function) returns.

于 2013-03-30T05:51:45.503 回答