Информационное окно карт Google дает одинаковый результат на разных маркерах - PullRequest
2 голосов
/ 22 января 2012

У следующей проблемы, информационное окно, дает одинаковый результат на разных маркерах. Когда я отлаживаю за пределами функции geocoder.geocode , она показывает правильную информацию, но внутри всегда то же самое (первое). часть suppid - это когда я отлаживаю переменную i внутри нее показывает правильное значение.

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')
                }
            });
        }

1 Ответ

3 голосов
/ 22 января 2012

Вызов Geocoder.geocode(request, callback) является асинхронным . Когда сервер отвечает, вызывается функция обратного вызова. Обычно к этому времени цикл 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 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...