我有一套方向,我试图用不同的颜色渲染。我要求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循环中的索引)附加到每个请求,以便可以从结果处理函数访问它?
答案 0 :(得分:1)
您需要使用closure scoped variables来执行此操作。当您尝试在路由回调函数中使用i
时,您正在使用一个名为闭包的概念,其中可以从内部函数访问在父函数中声明的变量。
但是使用closures in a loop有自己的问题,因为闭包变量的相同实例将在循环内创建的所有内部函数之间共享,因此当调用内部函数时,您将获得分配给的最后一个值循环中的变量。
这里的解决方案是在循环内创建一个局部闭包,如下所示
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)
}
答案 1 :(得分: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]));
答案 2 :(得分:0)
function(result,status)
中可用。有关说明和一些示例,请参阅here。由于您在创建回调时知道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()
时锁定了我需要的变量。