2017-11-25 125 views
-1

我有一些JSON,其中包含一些要在包含标记和信息窗口的Google地图上显示的位置。嵌套关闭中无法识别循环中的变量

通过一个简单的循环,我可以在地图上创建标记(有很多示例将许多标记放在一张地图上),但是我有一个额外的难度:因为我在JSON中有物理地址,我必须先对它们进行地理编码,然后转换为坐标。

无论如何,我得到了这个工作太:对于每个循环,每个JSON项目被翻译成其坐标和标记添加

但这里谈到的问题:在地理编码回调我无法访问我的电流JSON项目(我需要它来建立我的信息窗口)......它总是返回最后一个JSON的项目,所以它的无用

这里是一个工作片段:

var locations = [{"name":"Le Ginestre","address":"Via G. Marconi, Tremestieri Etneo"},{"name":"Le Zagare","address":"Via Manzoni, San Giovanni La Punta"},{"name":"Katan\u00e8","address":"Via Quasimodo 1, Gravina di Catania"}]; 
 

 
function initMap(){ 
 

 
    if (locations.length > 0){ 
 

 
     var i; 
 
     var map; 
 
     var location; 
 
     var geocoder; 
 
     var position; 
 
     var marker; 
 
     var bounds = new google.maps.LatLngBounds(); 
 
     var mapOptions = { 
 
      mapTypeId: 'roadmap' 
 
     }; 
 

 
     map = new google.maps.Map(document.getElementById("map"), mapOptions); 
 
     var infoWindow = new google.maps.InfoWindow(); 
 

 
     for(i = 0; i < locations.length; i++){ 
 
      location = locations[i]; 
 
      geocoder = new google.maps.Geocoder(); 
 
      geocoder.geocode({ 'address': location.address }, function(results, status){ 
 
       console.log(location); // THIS RETURNS ALWAYS THE LAST JSON ITEM 
 
       if (status === 'OK') { 
 
        position = results[0].geometry.location; 
 
        bounds.extend(position); 
 
        map.fitBounds(bounds); 
 
        marker = new google.maps.Marker({ 
 
         position: position, 
 
         map: map 
 
        }); 
 

 
        google.maps.event.addListener(marker, 'click', (function(marker) { 
 
         return function() { 
 
          // AND OF COURSE THIS SHOWS THE WRONG ADDRESS 
 
          infoWindow.setContent(location.address); 
 
          infoWindow.open(map, marker); 
 
         } 
 
        })(marker)); 
 
       } 
 
      }); 
 
     } 
 

 
     google.maps.event.addListenerOnce(map, 'bounds_changed', function() { 
 
      this.setCenter(bounds.getCenter()); 
 
     }); 
 
    } 
 
}
#map { 
 
    width:100%; 
 
    height:300px; 
 
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA222wozVyNudm3i0A2Tr_Vlmh_RipQ284&callback=initMap" async defer></script> 
 

 
<div id="map"></div>

正如你看到的,console.log(location); // THIS RETURNS ALWAYS THE LAST JSON ITEM行是自我解释,并标记上点击打开信息窗口始终

我读了一些StackOverflow的职位相同的地址(即JavaScript closure inside loops – simple practical example),但虽然问题是类似的,我不明白很多...

请任何帮助吗?由于

回答

1

好吧,我搜索好,我找到了答案,这要归功于以下文章:

https://decembersoft.com/posts/understanding-javascript-closures-in-for-loops/ http://www.teknically-speaking.com/2013/01/closures-in-loops-javascript-gotchas.html

这里是一个工作示例:

var locations = [{"name":"Le Ginestre","address":"Via G. Marconi, Tremestieri Etneo"},{"name":"Le Zagare","address":"Via Manzoni, San Giovanni La Punta"},{"name":"Katan\u00e8","address":"Via Quasimodo 1, Gravina di Catania"}]; 
 

 
function initMap(){ 
 

 
    if (locations.length > 0){ 
 

 
     var i, map, position, marker, location, geocoder; 
 
     var bounds = new google.maps.LatLngBounds(); 
 
     var mapOptions = { 
 
      mapTypeId: 'roadmap' 
 
     }; 
 

 
     map = new google.maps.Map(document.getElementById("map"), mapOptions); 
 
     var infoWindow = new google.maps.InfoWindow(); 
 

 
     for(i = 0; i < locations.length; i++){ 
 
      location = locations[i]; 
 
      
 
      // put geocoder stuff in a closure 
 
      (function(item){ 
 
       var name = '<b>' + item.name + '</b>'; 
 
       var address = item.address; 
 
       
 
       geocoder = new google.maps.Geocoder(); 
 
       return geocoder.geocode({ 'address': address }, function(results, status){ 
 
        if (status === 'OK') { 
 
         position = results[0].geometry.location; 
 
         bounds.extend(position); 
 
         map.fitBounds(bounds); 
 
         marker = new google.maps.Marker({ 
 
          position: position, 
 
          map: map 
 
         }); 
 

 
         google.maps.event.addListener(marker, 'click', (function(marker) { 
 
          return function() { 
 
           infoWindow.setContent(name + '<br>' + address); 
 
           infoWindow.open(map, marker); 
 
          } 
 
         })(marker)); 
 
        } 
 
       }); 
 
      })(location); 
 
     } 
 

 
     google.maps.event.addListenerOnce(map, 'bounds_changed', function() { 
 
      this.setCenter(bounds.getCenter()); 
 
     }); 
 
    } 
 
}
#map { 
 
    width:100%; 
 
    height:300px; 
 
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyA222wozVyNudm3i0A2Tr_Vlmh_RipQ284&callback=initMap" async defer></script> 
 

 
<div id="map"></div>

希望这可以帮助人们尝试g在谷歌地图上工作