在单页应用程序上重用谷歌地图API实例

Reuse instance of Google Maps API on Single Page Application

本文关键字:谷歌地图 API 实例 程序上 单页 应用 应用程序      更新时间:2023-09-26

假设我有一个单页应用程序(Angular JS应用程序),并在元素id googleMap-上绘制一个Google Map实例

var mapInstance = new google.maps.Map(document.getElementById(`googleMap`), mapOption)

然后我浏览应用程序路由,因此,破坏了googleMapDOM元素,最后我回到了带有该元素的路由,现在我必须在该元素上重新绘制地图。

重新绘制地图的正确方法是什么?

正如我在这个答案中所读到的,我不必重新创建它,而是使用相同的实例。

我会小心

$scope.on('$destroy', function(){
    mapInstance = null;
})

我有一个包含mapDOM元素的指令,调用这个方法从数据层中删除所有映射引用,所有侦听器,然后将映射设置为null。我在页面导航和重新创建映射实例之间检查堆,但旧的映射仍在堆中,导致内存使用量不断增加。

此外,你链接的答案建议重新使用你的地图实例,而不是试图删除它。谷歌地图开发人员也建议这种方法。我找到的解决方案是将directive元素传递给服务,并在新的子元素上添加一个子元素来创建映射。如果映射已经存在,只需将mapdiv附加到directive元素即可。下面是我的代码。

ng视图元素

<map-container></map-container>

指令

angular.module('project')
  .directive('mapContainer', function($timeout, mapService) {
     return {
       template: '<div></div>',
       restrict: 'E',
       replace: true,
       link: function(scope, element) {
         $timeout(function () {
           //Use the $timeout to ensure the DOM has finished rendering
           mapService.createMap(element).then(function() {
              //map now exists, do whatever you want with it
           });
        });
      }
    };
 })

服务

angular.module('project')
  .service('mapService', function($q) {
    var lat = -33.1798;
    var lng = 146.2625;
    var minZoom = 5;
    var maxZoom = 20;
    var zoom =  6;
    var mapOptions = null;
    var map = null;
    function initialiseGmap(element) {
      return $q(function (resolve) {
        if (map) {
          //Map already exists, append it
          element.append(map.getDiv());
          resolve();
        } else {
          //No map yet, create one
          element.append('<div id="map_canvas"></div>');
          mapOptions = {
            zoom: zoom,
            center: new google.maps.LatLng(lat, lng),
            styles: hybridMap, //your style here
            minZoom: minZoom,
            maxZoom: maxZoom,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            mapTypeControl: false,
            streetViewControl: false,
            panControl: false,
            scaleControl: true,
            zoomControl: false
          };
          map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
          //create any map listeners you want here. If you want to add data to the map and add listeners to those, I suggest a seperate service.
          resolve();
        }
      });
    }
    return {
      createMap: function(elem) {
        return initialiseGmap(elem);
      },
      getMap: function() {
        return map;
      },
      //Create as many functions as you like to interact with the map object
      //depending on our project we have had ones to interact with street view, trigger resize events etc etc.
      getZoom: function() {
        return zoom;
      },
      setZoom: function(value) {
        map.setZoom(zoom);
      }
    };
  });

这个问题有angularjs标记,所以我认为这是一个Angular JS应用程序。在这种情况下,您可能不应该在页面控制器中执行此操作。

您可以使用预先存在的指令,如https://angular-ui.github.io/angular-google-maps/#!/或者你可以自己写指令。

如果您编写自己的指令,那么每次使用$scope.on('$destroy',fn)事件销毁指令时,都应该销毁googlemap实例。像这样。。

$scope.on('$destroy', function(){
    mapInstance = null;
})

每次呼叫:

map = new google.maps.Map(document.getElementById('xx'), mapOptions);

你消耗了你的谷歌地图配额。小心!

在我的案例中,帮助谷歌地图的超时重新初始化解决了这个问题。

 setTimeout(function(){ initialize() }, 30);

通过销毁先前动态创建的元素可以杀死初始化的实例,但这更难。。。