0

我在使用Google地图V3 API时遇到了一些麻烦。重新加载数据时无法删除Google地图标记

这里是我的AngularJS指令:

; 
(function() { 
"use strict"; 

angular.module('LoVendoApp.directives') 
    .directive('map', ['SimpleRETS', 'InfoWindowService', 'McOptions', 'ModalOptions', '$rootScope', '$parse', '$uibModal', '$timeout', 'SafetyFilter', 
     function (SimpleRETS, InfoWindowService, McOptions, ModalOptions, $rootScope, $parse, $uibModal, $timeout, SafetyFilter) { 
      return { 
       restrict: 'A', 
       scope: { 
        requestObj: '=' 
       }, 
       link: function (scope, el, attrs) { 
        //Creating map instance with GoogleMaps API 
        var map = new google.maps.Map(el[0], { 
         center: { 
          lat: 25.7742700, 
          lng: -80.1936600 
         }, 
         zoom: 8 
        }); 

        //Markers array 
        var markers = []; 
        console.log('on init = ', markers.length); 

        /** 
        * Creates new google maps 
        * marker 
        * 
        * @param {Object} param 
        * 
        */ 

        function _newGoogleMapsMarker(param) { 
         var r = new google.maps.Marker({ 
          map: param._map, 
          position: new google.maps.LatLng(param._lat, param._lng), 
          title: param._head, 
          icon: param._icon 
         }); 
         if (param._data) { 
          google.maps.event.addListener(r, 'click', function() { 
           // this -> the marker on which the onclick event is being attached 
           if (!this.getMap()._infoWindow) { 
            this.getMap()._infoWindow = new google.maps.InfoWindow(); 
           } 
           this.getMap()._infoWindow.close(); 
           var content = InfoWindowService.getContent(param._data); 

           this.getMap()._infoWindow.setContent(content); 
           //Creates event listener for InfoWindow insances 
           google.maps.event.addListener(this.getMap()._infoWindow, 'domready', function() { 
            $("#iw_container") 
             .off("click") 
             .on("click", modalListener); 
            //Opens modal when click is listened 
            function modalListener() { 
             var modalOptions = ModalOptions.getHouseDetailOptions(param._data); 
             var modalInstance = $uibModal.open(modalOptions); 
            } 
           }); 
           this.getMap()._infoWindow.open(this.getMap(), this); 
          }); 
         } 
         return r; 
        } 
        //Handling request with SimpleRETS service factory 
        scope.$on('loadMap', function() { 
         SimpleRETS.requestHandler(scope.requestObj).then(dataReceived, dataError); 

         function dataReceived(res) { 
          if (markers.length > 0) { 
           for (var k = 0; k > markers.length; k++) { 
            markers[k].setMap(null); 
            console.log('removing! #', k); 
           } 
           markers = []; 
           console.log('removed!'); 
          } 
          var results = res.filter(SafetyFilter.filterData); 
          $rootScope.globalHousesData = results; 
          if (markers.length == 0) 
           $timeout(loadMarkers(results), 1000); 
         } 

         function dataError(error) { 
          console.log('mapError', error); 
         } 

        }); 
        //Randomizes position for matching coordinates 
        function randomPos() { 
         return Math.random() * (0.0001 - 0.00005) + 0.00005; 
        } 

        function loadMarkers(results) { 
         // Fetching marker options from service 
         var options = McOptions.getOptions; 
         for (var i = 0; i < results.length; i++) { 
          var marker = _newGoogleMapsMarker({ 
           _map: map, 
           _icon: 'assets/images/icon.png', 
           _lat: results[i].geo.lat, 
           _lng: results[i].geo.lng, 
           _head: '|' + new google.maps.LatLng(results[i].geo.lat, results[i].geo.lng), 
           _data: results[i] 
          }); 
          markers.push(marker); 
         } 
         var markerCluster = new MarkerClusterer(map, markers, options); 
        } 
        //Initializes event to load m 
        scope.$broadcast('loadMap'); 
       } 
      } 
     } 
    ]); 

})(); 

正如你可以看到我已经要疯了与console.logs,看看有什么问题我的逻辑。它看起来有点压倒性,但我只有4个主要组件或行动。第一予初始化地图:

var map = new google.maps.Map(el[0], { 
     center: { 
      lat: 25.7742700, 
      lng: -80.1936600 
     }, 
     zoom: 8 
    }); 

的I实例化一个标记阵列:var markers = [];

然后,我有2层主要的功能。一个创建新的标记:_newGoogleMapMarkers(param)

该函数接受一个param对象,该对象基本上包含地图对象,位置坐标,图标,标题以及InfoWindow中可用的一些内容。另外,我正在为所有InfoWindows提供onClick监听器,以在我的应用中打开外部模式。

其他功能时,应标记数组为空被触发,它从我使用(SimpleRETS)

这一切都是由事件触发外部API加载新的数据`$每当过滤器发生变化时触发$ broadcast('loadMap'),用户与某些东西交互等。

问题是,即使我在调用loadMarkers()函数时标记数组为空在迭代和做标记[k] .setMap(null))之后,旧标记留在地图中,创建一个每个负载加载500个标记时会出现大量标记。我甚至试图在下一次加载之前marker数组为空后设置1000ms的超时时间,以查看它是否以任何方式提供帮助,但事实并非如此。

那么你们怎么看?我会很感激你的任何建议。

回答

0

对于任何可能有同样问题的人。如果您使用的是markerclusterer jQuery Plugin,则在新标记加载之后清空标记数组之前,您必须使用markerCluster.clearMarkers();

所以基本上它最终会看起来像这样

if (markerCluster) { 
    markerCluster.clearMarkers(); 
    markers = []; 
} 

//Load new markers in the markers array 
[...] 
//Creating Cluster 
markerCluster = new MarkerClusterer(map, markers, options); 

那么你会做任何你需要获取数据和地图上的这个点更换标记,因为会明确标记和集群。