【问题标题】:Can't remove Google Map Markers when reloading data重新加载数据时无法删除 Google 地图标记
【发布时间】:2017-04-10 03:14:16
【问题描述】:

我在使用 google maps V3 API 时遇到了一些问题。

这是我的 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
  });

我实例化一个标记数组:var markers = [];

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

此函数接受一个参数对象,该对象基本上包含地图对象、位置坐标、图标、标题和一些应该在信息窗口中可用的内容。此外,我正在向所有 InfoWindows 附加一个 onClick 侦听器,以在我的应用中打开一个外部模式。

当标记数组为空并且它从我正在使用的外部 API (SimpleRETS) 加载新数据时,应该触发另一个函数

这都是由事件 `$scope.$broadcast('loadMap') 触发的,该事件在每次过滤器更改、用户与某些内容交互等时触发。

问题是,即使我在标记数组为空时调用loadMarkers() 函数(并且在迭代和执行标记[k].setMap(null) 之后),旧标记仍保留在地图中,创建一个每次加载 500 个标记时会出现大量标记。我什至尝试在标记数组为空之后在下一次加载之前设置 1000 毫秒的超时,以查看它是否有任何帮助,但它没有。

那你们觉得呢?如果您有任何建议,我将不胜感激。

【问题讨论】:

    标签: javascript angularjs google-maps google-maps-api-3 angularjs-directive


    【解决方案1】:

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

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

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

    然后你会做任何你需要获取数据和替换标记的事情,因为从地图上的这一点开始,标记和集群将被清除。

    【讨论】:

      猜你喜欢
      • 2017-10-29
      • 2012-11-06
      • 2019-08-16
      • 1970-01-01
      • 2012-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多