Javascript GoogleMapsAPI在单页应用程序中的重用实例
假设我有一个单页应用程序(Angular JS应用程序),我在元素idJavascript GoogleMapsAPI在单页应用程序中的重用实例,javascript,angularjs,google-maps,google-maps-api-3,Javascript,Angularjs,Google Maps,Google Maps Api 3,假设我有一个单页应用程序(Angular JS应用程序),我在元素idgoogleMap- var mapInstance = new google.maps.Map(document.getElementById(`googleMap`), mapOption) 然后我浏览应用程序路由,由于这个原因,我销毁了googleMapDOM元素,最后我使用这个元素返回路由,现在我必须在这个元素上重新绘制地图 重新绘制地图的正确方法是什么 正如我在中所读到的,我不必重新创建它,而是使用相同的实例 这个
googleMap
-
var mapInstance = new google.maps.Map(document.getElementById(`googleMap`), mapOption)
然后我浏览应用程序路由,由于这个原因,我销毁了googleMap
DOM元素,最后我使用这个元素返回路由,现在我必须在这个元素上重新绘制地图
重新绘制地图的正确方法是什么
正如我在中所读到的,我不必重新创建它,而是使用相同的实例 这个问题有angularjs标记,所以我假设这是一个angularjs应用程序。在这种情况下,您可能不应该在页面控制器中执行此操作 您可以使用预先存在的指令,如或编写自己的指令 如果您编写自己的指令,那么您应该在每次使用$scope.on(“$destroy”,fn)事件销毁该指令时销毁google map实例。像这样
$scope.on('$destroy', function(){
mapInstance = null;
})
我会小心的
$scope.on('$destroy', function(){
mapInstance = null;
})
我有一个包含map-DOM元素的指令,调用此方法从数据层、所有侦听器中删除所有映射引用,然后将映射设置为null。我正在检查页面导航和映射实例之间的堆,但旧映射仍在堆中,导致内存使用率不断增加
您链接的答案还建议重新使用地图实例,而不是尝试删除它。谷歌地图开发者也推荐这种方法。我找到的解决方案是将您的directive元素传递给一个服务,并在该服务上附加一个子元素,在新的子元素上创建映射。如果映射已经存在,只需将map div附加到指令元素。下面是我的代码
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);
}
};
});
angular.module('project'))
.directive('mapContainer',function($timeout,mapService){
返回{
模板:“”,
限制:'E',
替换:正确,
链接:功能(范围、元素){
$timeout(函数(){
//使用$timeout确保DOM已完成渲染
createMap(元素).then(函数(){
//地图现在已经存在,你想用它做什么都行
});
});
}
};
})
服务
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);
}
};
});
angular.module('project'))
.service('mapService',函数($q){
var lat=-33.1798;
var lng=146.2625;
var-minZoom=5;
var-maxZoom=20;
var-zoom=6;
var-mapOptions=null;
var-map=null;
函数initialiseGmap(元素){
返回$q(函数(解析){
如果(地图){
//映射已存在,请附加它
append(map.getDiv());
解决();
}否则{
//还没有地图,创建一个
元素。追加(“”);
映射选项={
缩放:缩放,
中心:新google.maps.LatLng(lat,lng),
样式:hybridMap,//您的样式在这里
minZoom:minZoom,
maxZoom:maxZoom,
mapTypeId:google.maps.mapTypeId.ROADMAP,
mapTypeControl:false,
街景控制:错误,
泛控制:错误,
scaleControl:对,
动物控制:错误
};
map=new google.maps.map(document.getElementById('map_canvas'),mapOptions);
//在这里创建您想要的任何映射侦听器。如果您想向映射添加数据并向这些映射添加侦听器,我建议使用单独的服务。
解决();
}
});
}
返回{
createMap:函数(元素){
返回初始ISegmap(elem);
},
getMap:function(){
返回图;
},
//创建与贴图对象交互的任意多个函数
//根据我们的项目,我们有一个与街景互动,触发调整大小事件等。
getZoom:function(){
返回缩放;
},
setZoom:函数(值){
map.setZoom(缩放);
}
};
});
在我的例子中,超时帮助重新初始化Google地图解决了这个问题
setTimeout(function(){ initialize() }, 30);
通过销毁以前动态创建的元素可以杀死初始化的实例,但这更难 每次打电话时:
map = new google.maps.Map(document.getElementById('xx'), mapOptions);
你使用你的谷歌地图配额。
小心 是的,这是一个角度的JS应用程序在一个案例中,我写了我自己的指令,我必须在
$destroy
函数中做什么,以及如何重新绘制它?我已经更新了我的答案,告诉我如何销毁它。我不知道为什么需要重新绘制它,因为它所连接的DOM已经不存在了。编译新指令时,只需创建一个新的mapInstance。我确实在您的链接中看到了关于不销毁和重新创建地图的其他问题。我不确定这是否是常见做法,如果在指令中创建mapInstance,您将无法做到这一点。您需要在应用程序的更高级别上创建一个mapInstance并重用它。你可能想深入研究谷歌地图的代码,看看他们是如何做到的。我已经为这个问题添加了一个答案,我觉得它解决了这个问题。我希望你能过来看看。它为我工作,我能够在单页应用程序中重用和访问同一实例。作为一个经验有限的人,如果你们中的任何一方/双方都认为这个答案解决了这个问题,那么什么是确保其他人直接找到答案的最佳方法@URL87