Проблема с закрытием PHP javascript в Google Maps v3

#php #javascript #jquery #google-maps-api-3

#php #javascript #jquery #google-maps-api-3

Вопрос:

Мое приложение отображает множество маркеров на карте, считанной из базы данных MySQL, и я хочу отобразить некоторый контент в каждом из информационных окон. Моя проблема в том, что infowindows будет отображать содержимое только последней записи в моей базе данных. Ниже приведен мой код, где я просто пытаюсь отобразить название местоположения. Я попытался предупредить переменные, чтобы увидеть, действительно ли они отображают правильный контент, которым они являются. Я понимаю, что это проблема с закрытием javascript, но я не знаю, как это исправить.

 var startLat;
var startLng;
var locationName;

<?php foreach($workstations as $workstation):?>
    startLat = "<?php echo $workstation['lat']?>";
    startLng = "<?php echo $workstation['lng']?>";
    locationName = "<?php echo $workstation['name']?>";

    var marker = new google.maps.Marker({
        position: new google.maps.LatLng(startLat, startLng),
        map: map,
        icon: "images/purple.png"
    });

    //load all the infowindow content
    var contentString = [
                    '<div id="InfoText" style="margin: 0px; padding: 0px; overflow: hidden; border:0px">',
                    '<div class="tabs"><ul><li><a href="#tab1">General</a></li>',
                    '<li><a href="#tab2">General 2</a></li></ul>',
                    '<div id="tab1">',
                    '<b>'   locationName   '</b> - '   locationName   '<BR>',
                    '<input id="save" type="submit" value="Reserve Today" onclick="saveStation(addMarker)" />',
                    '</div>',
                    '<div id="tab2">',
                    '</div>',
                    '</div>'
                           ].join('');

    //alert(contentString);
    var infowindow = new google.maps.InfoWindow({content: contentString});

    new google.maps.event.addListener(marker, 'click', (function(marker) {
        return function(){
            infowindow.open(map, marker);
            }
        })(marker));
<?php endforeach;?>
  

Ответ №1:

ДА. Это проблема с закрытием js. У вас есть одна переменная «marker», на которую указывают все прослушиватели событий maps. Попробуйте это вместо:

Поместите это вверху (перед циклом foreach):

 function addMarkerListener( mark, mp, win )
{
    new google.maps.event.addListener(
          mark, 
          'click', 
          function(){win.open(mp,mark)}
}
  

Затем вместо прослушивателя в конце вашего блока кода добавьте это:

 addMarkerListener( marker, map, infowindow );
  

По сути, в вашей версии происходит то, что js говорит: «Хорошо, я собираюсь создать функцию и заполнить ее переменной marker. Понял.» Когда приходит время для фактического вызова функции, она говорит: «Я ищу переменную ‘marker’, что в этой переменной?» К сожалению, тем временем это было переназначено, и теперь оно представляет самое последнее назначение.

С другой стороны, приведенная здесь версия сообщает JavaScript: «У меня есть эти совершенно новые переменные, они существуют только здесь, поэтому не ищите их нигде больше. При нажатии на одну из них отобразите значение, связанное с ней «. При нажатии на элемент JS говорит: «Хм … эта переменная была назначена только для использования в этом контексте, поэтому, я думаю, я буду использовать это «.

Я мог бы перейти к привязке переменных, и там задействованы некоторые интересные элементы лямбда-исчисления, но это многовато для данной области.

Комментарии:

1. Спасибо за вашу помощь! Я попробовал это, и это сработало. И спасибо за объяснение, действительно ясное.

Ответ №2:

Вы не должны выполнять цикл в PHP. Таким образом вы не только выводите массивные повторяющиеся блоки Javascript, но и создаете это:

 var infowindow = …
var infowindow = …
var infowindow = …
var infowindow = …
  

Вы перезаписываете свою собственную infowindow переменную, поэтому, очевидно, остается только последняя.

Просто подготовьте данные в PHP, затем используйте цикл Javascript для их обработки. Это также должно сделать проблемы с областью видимости более очевидными. В вашем случае infowindow переменная имеет единицу и может быть исправлена, как показано ниже:

 var workstations = <?php echo json_encode($workstations); ?>;

for (var i = 0; i < workstation.length; i  ) {
    var lat = workstations[i].lat;
    var lng = workstations[i].lng;
    var name = workstations[i].name;

    var marker = …
    var content = …
    var infowindow = … 

    (function (marker, infowindow) {
        google.maps.event.addListener(marker, 'click', function () {
            infowindow.open(map, marker);
        });
    })(marker, infowindow);
}