2017-11-25 6 views
-1

マーカーと情報ウィンドウを持つGoogleマップに表示する場所がいくつかあるJSONがあります。ループ内の変数がネストされたクロージャで認識されない

単純なループでは、マップ上にマーカーを作成することができます(1つのマップに多くのマーカーを配置する例がたくさんあります)が、難しいレベルです.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>

見ての通り、私は(すなわち、いくつかのStackOverflowの記事を読むconsole.log(location); // THIS RETURNS ALWAYS THE LAST JSON ITEM行が自己に説明すると、マーカーをクリックの上に開いた情報ウィンドウは、常に同じアドレス

を持っていますJavaScript closure inside loops – simple practical example)でも問題は同じですが、私は多くのことを理解していませんでした...

助けてくださいおかげ

答えて

1

[OK]を、私はより良い検索と私は答えを見つけ、以下の記事のおかげで:ここで

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 Googleマップで作業する

関連する問題