【问题标题】:MarkerCluster refresh after AJAX callAJAX 调用后 MarkerCluster 刷新
【发布时间】:2018-12-30 04:43:21
【问题描述】:

我有一个 AJAX 函数,可以根据某个角色根据用户查询帖子,这很好并且可以工作,但问题是我试图在 AJAX 完成并且帖子被查询后刷新 Google 地图上的标记。

在我的 AJAX 调用中,我将结果的 html 输出输入到一个 div 中,我试图让地图基本上识别和识别该 div 中的结果,并根据该 div 中的结果更新标记。

例如,当页面加载时,地图上最初有 18 个结果,当 AJAX 调用完成时,本来应该有 3 个结果,但是当我在 AJAX 调用后重新初始化地图时,原来的 18 个结果仍然出现在地图上。

我认为问题可能出在 $each 函数或 map 函数中,因为它没有正确更新标记。当我在每个函数中记录结果的标题时,所有 18 个原始结果都被返回,即使在 AJAX 调用完成并且有 3 个结果由 HTML 输出到结果 div 之后。

我希望我已经足够清楚地解释了我的问题,并希望有人可以帮助我。我将在下面粘贴所有相关代码。

获取结果的 AJAX 函数:

$('#private').on('click', function(e) {
  e.preventDefault();
  var owner = $(this).data('owner');
  var res = $('.total-matches').data('res');

  $('#stm_owner').val(owner);
  $('#stm_res').val(res);
  $(this).addClass('active');

  var data_form = $('.filters').closest('form').serialize();

  $.ajax({
    url: ajaxurl,
    dataType: 'json',
    context: this,
    data: data_form + '&action=ajax_filter',
    beforeSend: function() {
      $('.ajax-row').addClass('loading');
    },
    success: function(data) {
      $('.sorting').html(data.html);
      $('.map-results').html(data.html);
      $('.total-matches span').text(' ' + data.total);
      $('.ajax-row').removeClass('loading');
    },
    complete: function() {
      $('.timeago').timeago();
      initGoogleMap(markersInfo);
    }
  });
});

谷歌地图功能:

var markersInfo = $('.ia-map').map(function() {
  var info = {
    id: $(this).data('map-id'),
    address: $(this).data('map-address'),
    title: $(this).data('map-title'),
    price: $(this).data('map-price'),
    latitude: $(this).data('map-latitude'),
    longitude: $(this).data('map-longitude'),
    html: "<img src=" + $(this).data('map-image') + ">",
    link: $(this).data("map-link"),
    contentHtml: "<div class='image'>" + "<img src=" + $(this).data('map-image') + ">" + "</div>" + '<b>' + $(this).data('map-title') + '</b><br>' + "<div class='changeprice'><div style='display: none;' class='currency-selector'></div>" + $(this).data('map-price') + "</div>" + "<br><a href='" + $(this).data("map-link") + "'>More>></a>"
  };
  return info;
}).get();

var distinctMarkerInfo = [];
markersInfo.forEach(function(item) {
  if (!distinctMarkerInfo.some(function(distinct) {
      return distinct.id == item.id;
    })) distinctMarkerInfo.push(item);
});

initGoogleMap(distinctMarkerInfo);

// GMAP ON SEARCH RESULTS PAGE
function initGoogleMap(markersInfo) {
  var mapOptions = {
      // zoom: 2,
      // center: new google.maps.LatLng(53.334430, -7.736673)
    },
    bounds = new google.maps.LatLngBounds(),
    mapElement = document.getElementById('map_results'),
    map = new google.maps.Map(mapElement, mapOptions);
  var markerList = []; // create an array to hold the markers
  var geocoder = new google.maps.Geocoder();
  var iconBase = '../assets/images/';

  $.each(markersInfo, function(key, val) {
    var marker = new google.maps.Marker({
      //map: map,
      position: {
        lat: parseFloat(val.latitude),
        lng: parseFloat(val.longitude)
      },
      title: val.title,
      icon: iconBase + 'single.png',
      info: new google.maps.InfoWindow({
        content: val.contentHtml
      })
    });

    markerList.push(marker); // add the marker to the list

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

    var loc = new google.maps.LatLng(val.latitude, val.longitude);
    bounds.extend(loc);
  });

  map.fitBounds(bounds);
  map.panToBounds(bounds);

  markerCluster = new MarkerClusterer(map, markerList, {
    imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
  });
}

最后是地图 html:

<div id="map_results" style="width:100%; height:600px;"></div>

以及 AJAX 调用后每个结果输出到结果 div 中的 div

<div class="ia-map" data-price="<?php echo esc_attr($data_price) ?>" data-date="<?php echo get_the_date('Ymdhi') ?>" data-mileage="<?php echo esc_attr($data_mileage); ?>" data-map-id="<?php echo $id; ?>" data-map-address="<?php echo $location; ?>" data-map-title="<?php echo $title; ?>" data-map-price="<?php echo esc_attr($price); ?>" data-map-latitude="<?php echo $lat; ?>" data-map-longitude="<?php echo $lng; ?>" data-map-image="<?php echo esc_url($img[0]); ?>" data-map-link="<?php the_permalink() ?>" <?php if(isset($distance)): ?>data-distance="<?php echo esc_attr(floatval($distance)); ?>"<?php endif; ?>></div>

最后是结果 div 本身

<div class="map-results" style="display: none;"></div>

【问题讨论】:

  • 我看不到您如何在 ajax 完成事件中获得 markerInfo 变量的价值。
  • @FahamShaikh 我在完成时调用initGoogleMap(markersInfo) 的唯一原因是因为我认为我必须重新初始化地图才能刷新标记。老实说,我不确定我在那里做什么,哈哈
  • 你调用函数是对的,但传递变量是错误的。如果您在 ajax 完成时收到标记数据,那么您应该以您需要的格式编译它并传递给初始化函数。
  • @FahamShaikh 是的,我不一定会获得成功的标记数据,但从某种意义上说,结果 div 会在 ajax 调用后更新,并且只会显示相关结果 (带有ia-map 类的div) 但除此之外,我不知道如何通过markercluster 将数据传回。如果您可以编辑我上面的代码并向我展示您在说什么,我将不胜感激:)
  • 查看我的回复。如果您在 ajax 完成后在任何输入中填充数据,那么您可以使用我的 onChange 函数中的代码并完成工作。祝你好运。

标签: javascript jquery ajax wordpress google-maps


【解决方案1】:

这是我基于您的 ajax 调用的答案(您只需在代码中更改此内容)。

$.ajax({
    url: ajaxurl,
    dataType: 'json',
    context: this,
    data: data_form + '&action=ajax_filter',
    beforeSend: function(){
        $('.ajax-row').addClass('loading');
    },
    success: function (response) {
       //This logs the ajax response.
       console.log(response);
       $('.sorting').html(response.html);
       $('.map-results').html(response.html);
       $('.total-matches span').text(' ' + response.total);
       $('.ajax-row').removeClass('loading');
       var ajaxMarkersInfo = [];
       $('.map-results .ia-map').each(function(index, el){
           //var ajaxMarker = [];
           var mapID = $(this).attr('data-map-id');
           var mapAddress = $(this).attr('data-map-address');
           var mapTitle = $(this).attr('data-map-title');
           var mapPrice = $(this).attr('data-map-price');
           var mapLatitude = $(this).attr('data-map-latitude');
           var mapLongitude = $(this).attr('data-map-longitude');
           var mapHTML = "<img src=" + $(this).attr('data-map-image') + ">";
           var mapLink = $(this).attr('data-map-link');
           var mapContentHTML = "<div class='image'>" + "<img src=" + $(this).attr('data-map-image') + ">" + "</div>" + '<b>' + $(this).attr('data-map-title') + '</b><br>' + "<div class='changeprice'><div style='display: none;' class='currency-selector'></div>" + $(this).attr('data-map-price') + "</div>" + "<br><a href='" + $(this).attr("data-map-link") + "'>More>></a>";
           var ajaxMarker = {
               id: mapID,
               address: mapAddress,
               title: mapTitle,
               price: mapPrice,
               latitude: mapLatitude,
               longitude: mapLongitude,
               html: mapHTML,
               link: mapLink,
               contentHtml: mapContentHTML
           };
           ajaxMarkersInfo.push(ajaxMarker);
       });
       console.log(ajaxMarkersInfo);
       initGoogleMap(ajaxMarkersInfo);
    },
    complete: function() {
        $('.timeago').timeago();

    }
});

这应该对您有用,但为了验证,我已在控制台中记录了 ajaxMarkersInfo 变量,因此您可以从代码中记录 info 变量并进行比较。

我希望这会有所帮助。

【讨论】:

  • 我在 ajaxMarker.push 中遇到错误,我不知道如何解决它..
  • id: address: 等会出现错误......当我摆脱这些错误时,不再有错误。例如ajaxMarker.push(mapID);
  • 对不起,我现在有点困了(现在是晚上 3:17)。我之前注意到了这个错误,而不是完全修复它,我只做了一部分。它现在应该可以工作了。
  • 抱歉让你这么晚了。我不再收到错误,但控制台现在正在记录一个空数组,而在它工作之前,我使用 mapID 解释它的方式...
  • 请分享记录数据的输出。我首先记录了 ajax 请求的响应,这将有助于确定您的问题。
【解决方案2】:

我已经完成了与您尝试类似的操作,因此您可以查看我的代码,对其进行修改并将其用于您的目的。

var map;
var elevator;
var markers = [];
function mapinitialize() {
    var myOptions = {
        zoom: 5,
        center: new google.maps.LatLng(23.603296, 81.885962),
        mapTypeId: 'roadmap',
        styles: [
            {
                "featureType": "administrative",
                "elementType": "geometry",
                "stylers": [
                {
                    "color": "#ff8040"
                },
                {
                    "weight": 1.5
                }
                ]
            },
            {
                "featureType": "administrative",
                "elementType": "labels",
                "stylers": [
                {
                    "visibility": "off"
                }
                ]
            },
            {
                "featureType": "poi",
                "stylers": [
                {
                    "visibility": "off"
                }
                ]
            },
            {
                "featureType": "road",
                "stylers": [
                {
                    "visibility": "off"
                }
                ]
            },
            {
                "featureType": "transit",
                "stylers": [
                {
                    "visibility": "off"
                }
                ]
            }
        ]
    };
    map = new google.maps.Map(document.getElementById('hp-map-js'), myOptions);
}
function mapMark(receivedAddress = '') {
    //Loop through all the markers and remove
    for (var i = 0; i < markers.length; i++) {
        markers[i].setMap(null);
    }
    markers = [];
    var icon = '/wp-content/themes/sssbv/assets/img/homepage/map/logo-map.png';
    var addresses = receivedAddress != '' ? receivedAddress : ['Norway', 'Africa', 'Asia','North America','South America'];
    console.log(addresses);
    for (var x = 0; x < addresses.length; x++) {
        //I am geocoding the coordinates from individual location address.
        jQuery.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address='+addresses[x]+'&sensor=false', null, function (data) {
            var p = data.results[0].geometry.location;
            var latlng = new google.maps.LatLng(p.lat, p.lng);
            map.setCenter(data.results[0].geometry.location);
            map.setZoom(6);
            window.setTimeout(function() {
                markers.push( new google.maps.Marker({
                    position: latlng,
                    map: map,
                    animation: google.maps.Animation.DROP,
                    icon: icon
                }));
            }, (x+1*200));
        });
    }
}
jQuery(document).ready(function($) {
    var loaded = false;
    //This is the part you have to change.
    //Instead of on change you will use your ajax output on completion.
    $(".location-selector").on('change', '#district-js', function(e){
        e.preventDefault();
        //Here I am getting the state and district name.
        var selectedDistrictVal = $(this).val();
        selectedDistrictVal = selectedDistrictVal.replace('-', ' ');
        var selectedStateVal = $('.location-selector #state-js').val();
        selectedStateVal = selectedStateVal.replace('-', ' ');
        if (selectedDistrictVal != '') {
            var createdAddress = [];
            createdAddress.push(selectedDistrictVal);
            mapMark(createdAddress);
        }
    });
});

【讨论】:

  • 感谢您的帮助,但在这方面我是新手,所以我不确定如何使用您的代码更改和更新我的代码,您能帮我解决吗请问?
  • @MattH 如果不了解 ajax 请求的输出,这有点困难。你能帮我提供那个输出数据吗?
  • 我该怎么做?
  • @MattH 如果您使用我的示例代码,您只需以 json 对象格式传递地址。如果您使用自己的代码,那么我可能需要粘贴另一个解决方案。
  • 那么在成功时你会得到多个带有ia-map类的div吗?
猜你喜欢
  • 1970-01-01
  • 2013-06-24
  • 1970-01-01
  • 2017-03-14
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
  • 2018-02-24
  • 1970-01-01
相关资源
最近更新 更多