2012-01-22 14 views
2

以下の問題が発生すると、情報ウィンドウでさまざまなマーカーで同じ結果が得られます。 の外側でデバッグするとき、geocoder.geocode関数は正しい情報を表示しますが、常に同じ(最初のもの)の内部に表示します。私はそれが正しい値を示している私の変数をデバッグする時suppidの部分です。Googleマップの情報ウィンドウに異なるマーカーで同じ結果が表示される

var optionMap = { 
      zoom: 16, 
      MapTypeId: google.maps.MapTypeId.ROADMAP, 
      panControl: false, 
      zoomControl: false, 
      mapTypeControl: false, 
      scaleControl: false, 
      streetViewControl: false, 
      overviewMapControl: false 
     }; 

     var map = new google.maps.Map(document.getElementById('map'), optionMap); 

     var geocoder = new google.maps.Geocoder(); 

     var latlngbounds = new google.maps.LatLngBounds(); 

     var icon = new google.maps.MarkerImage('images/gm_pin.png', 
     new google.maps.Size(20, 34), 
     new google.maps.Point(0,0), 
     new google.maps.Point(10, 34)); 

     for(var i = 0; i < arrAddress.length; i++) { 

      var address = arrAddress[i]; 

      var html_title = "<div class='info'><h4>" + address + "</h4></div>"; 

      geocoder.geocode({ 
       'address': address 
      }, function (results, status) { 

       if(status == google.maps.GeocoderStatus.OK) { 


        var marker = new google.maps.Marker({ 
         map: map, 
         icon: icon, 
         html: html_title, 
         position: results[0].geometry.location 
        }); 

        var contentString = ''; 

        var infoWindow = new google.maps.InfoWindow({ 
         content: contentString 

         }); 

        google.maps.event.addListener(marker, 'mouseover', function() { 
         infoWindow.setContent(this.html); 
         infoWindow.open(map, this); 
        }); 

        google.maps.event.addListener(marker, 'mouseout', function() { 
         infoWindow.close(map, this); 
        }); 

        latlngbounds.extend(results[0].geometry.location); 

        if(i == arrAddress.length) { 
         map.fitBounds(latlngbounds); 
        } 

        google.maps.event.trigger(map, 'resize') 
       } 
      }); 
     } 

答えて

3

Geocoder.geocode(request, callback)is asynchronousへの呼び出し。サーバーが応答すると、コールバック関数が呼び出されます。通常この時間までに、forループは既に終了しています。これはあなたが記述した結果を正確に表すことができます。ループが終了した後に発生するコールバックでマーカーが作成され、最後にhtml_titleの値が使用されるため、各マーカーの内容は同じです。

これを修正する方法は、ループ内に変数html_titleを '取り込む'ループ内にクロージャを作成することです。このようにして、コールバックは正しい値html_titleを使用します。

JavaScriptでの典型的な明示的な閉鎖は、次のようになりますあなたのコードで

// Wrap a function in() and immediately call it with another() 
// Pass in the arguments in the second() 
// This causes them to be 'captured' inside the function 
(function(args) { /* Do something with args */ })("Hello", 42); 

、閉鎖ループ中にアドレスをキャプチャする必要があります。このありがとう

for(var i = 0; i < arrAddress.length; i++) { 
    var address = arrAddress[i]; 
    var html_title = "<div class='info'><h4>" + address + "</h4></div>"; 

    (function(address, title) { 
    // Inside the closure, we can use address and html_title 
    geocoder.geocode({'address': address /* captured */}, function (results, status) { 
     if(status == google.maps.GeocoderStatus.OK) { 
     var marker = new google.maps.Marker({ 
      map: map, 
      icon: icon, 
      html: title, /* captured */ 
      position: results[0].geometry.location 
     }); 

     var contentString = ''; 
     var infoWindow = new google.maps.InfoWindow({ 
      content: contentString 
     }); 

     // ... 
     } 
    }); 
    })(address, html_title); // <- Call function, pass the vars to be captured 
} 
+0

、一つの質問に取り組んでいます私はそれを別の機能に入れてもいいですか? – mebots

+0

技術的にはすでに別の機能です。だから、それを名前付き関数に移動し、その関数をループの内側から呼び出すことができます。 –

関連する問題