0

我有一组方向,我试图用不同的颜色渲染。我向 Google 请求方向,但我不确定如何存储状态,以便在返回路由结果时我可以用正确的颜色渲染每个状态。

所以,作为一个例子,我有这个对象:

{routes: [{start_lat : 0.0, start_lng : 0.0, end_lat : 1.0, end_lng : 1.0, color : "#ff0000"},
          {start_lat : 1.0, start_lng : 1.0, end_lat : 2.0, end_lng : 2.0, color : "#00ff00"}]}

这是我的功能:

directionsService = new google.maps.DirectionsService();
for(var i = 0; i < routes.length; i++){
    var dir_request = {
        origin : new google.maps.LatLng(routes[i]['start_lat'], routes[i]['stop_lng']),
        destination : new google.maps.LatLng(routes[i]['end_lat'], routes[i]['end_lng']),
        travelMode : google.maps.TravelMode.WALKING
    };
    directionsService.route(dir_request, function(result, status) {
        if(status == google.maps.DirectionsStatus.OK){
            // render with custom logic depending on which route this is here
        }
    })
}

如何将状态(例如,for 循环中的索引)附加到每个请求,以便可以从结果处理函数访问它?

4

3 回答 3

1

您需要使用闭包 范围的变量来做到这一点。当您尝试i在路由回调函数中使用时,您正在使用称为闭包的概念,其中通过在父函数中声明的变量可以从内部函数访问。

但是在循环中使用闭包有其自身的问题,因为闭包变量的同一个实例将在循环中创建的所有内部函数之间共享,因此当调用内部函数时,您将获得分配给变量的最后一个值环形。

这里的解决方案是在循环内部创建一个局部闭包,如下所示

directionsService = new google.maps.DirectionsService();
for (var i = 0; i < routes.length; i++) {
    (function (idx) {
        var dir_request = {
            origin: new google.maps.LatLng(routes[idx]['start_lat'], routes[idx]['stop_lng']),
            destination: new google.maps.LatLng(routes[idx]['end_lat'], routes[idx]['end_lng']),
            travelMode: google.maps.TravelMode.WALKING
        };
        directionsService.route(dir_request, function (result, status) {
            // the variable idx will refer to the array index for the current iteration
            if (status == google.maps.DirectionsStatus.OK) {
                // render with custom logic depending on which route this is here
            }
        })
    })(i)
}
于 2013-11-05T02:47:33.293 回答
1

一些答案已经描述了如何通过显式闭包解决问题。这是另一个使用Function.prototype.bind.

directionsService.route(dir_request, (function(result, status) {
    //the this keyword now refers to the correct route object
    console.log(this);

    if(status == google.maps.DirectionsStatus.OK){
        // render with custom logic depending on which route this is here
    }
}).bind(routes[i]));

编辑:

这是另一种有效的方法,无需bind. 在循环中内联范围安全函数效率不高,因为每次迭代都必须创建一个新函数。最好为此目的创建一个函数并重用它。

function createRouteCallback(route) {
    return function (result, status) {
        if(status == google.maps.DirectionsStatus.OK) {
            // render with custom logic depending on which route this is here

            //you can just use route here
            console.log(route);
        }
    };
}

然后在循环中你可以简单地做:

directionsService.route(dir_request, createRouteCallback(routes[i]));
于 2013-11-05T03:06:52.747 回答
0

马尔卡是对的。除非发生了奇怪的事情,否则所有函数的变量都可以在 callback 中使用function(result,status)。有关说明和一些示例,请参见此处。既然知道什么dir_request时候创建回调,就可以直接在回调代码中引用。i如果您需要访问该routes数组,您也应该可以参考。

如果您在获取值时遇到任何问题,可以尝试添加一个间接层:

function makeCallback(dir_request) {
    return function(result,status) {
        //your code, and you can refer to dir_request
    };
}

然后打电话

directionsService.route(dir_request, makeCallback(dir_request));

我必须在 Greasemonkey 脚本中这样做一次,以确保我需要的变量在function()创建时被锁定。

于 2013-11-05T02:47:07.500 回答