2017-11-25 174 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在谷歌地圖上工作