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

那麼你會做任何你需要獲取數據和地圖上的這個點更換標記,因爲會明確標記和集羣。