使用angular-google-maps将Google地图合并到应用
我需要一个在初始地图加载完成后运行函数ONCE的命令 - 但仅限于初始加载, 不是在每次地图操作之后
我无法使用idle
或tilesloaded
,因为这些都会在每次移动后被解雇......
我想要运行的函数需要获取映射边界,以便在初始页面加载时从服务器中提取数据
- 我希望这在初始加载时发生,然后是使用刷新map-control
的手动功能
- 如果我使用idle
或tilesloaded
来启动此操作,则会在用户移动地图的每个时间内提取服务器数据。
有没有人知道如何在初始地图加载后触发一次性命令以获取地图详细信息(边界等)?
我已经尝试将maps.getBounds()
放在第二个承诺函数中,但它不起作用。
注意,I've got a fiddle working here - 在定义$scope.map
控件/选项等之后,我无法将更多的承诺链接起来,因为它们不会返回承诺:
文档中的代码示例并未显示如何在 $scope.map
定义后链接承诺。
HTML
<div class="angular-google-map-container" ng-controller="MainCtrl">
<ui-gmap-google-map center="map.center" zoom="map.zoom" draggable="true" options="map.options" events="map.events" control="googlemap">
</ui-gmap-google-map>
</div>
控制器
myApp.controller('MainCtrl', function($scope, uiGmapGoogleMapApi) {
uiGmapGoogleMapApi
.then(function(maps){
$scope.map = {
center: {
latitude: 37.7749295,
longitude: -122.4194155
},
zoom: 12
events: {
tilesloaded: function (maps, eventName, args) {
myServiceFuntion(maps) // this work fine but fires every time
},
dragend: function (maps, eventName, args) {
myServiceFuntion(maps) // this work fine but fires every time
},
zoom_changed: function (maps, eventName, args) {
myServiceFuntion(maps) // this work fine but fires every time
}
}
}
$scope.bounds = maps.getBounds() // this gives me 'getBounds() not a function'
myServiceFuntion(maps); // this gives an error... ?
return maps; //no promise returned here so no chance to delay the function below
})
.then(function(maps){
//is this where i need to put my function ? doesn't delay on map load since no promise returned...
});
});
显然,maps
承诺返回的uiGmapGoogleMapApi
对象与maps
等事件返回的tilesloaded
对象完全不同......非常令人困惑。
此外,the FAQ仅指示如何使用tilesloaded
来获取地图实例 - 由于已经描述的原因,该实例无法正常工作。
答案 0 :(得分:9)
我认为“正确”的方法是通过将IsReady
服务注入控制器来使用API uiGmapIsReady
功能。请参阅the documentation。
使用uiGmapIsReady
承诺,然后可以将map
传递给函数/服务等,代码如下:
uiGmapIsReady.promise() // this gets all (ready) map instances - defaults to 1 for the first map
.then(function(instances) { // instances is an array object
var maps = instances[0].map; // if only 1 map it's found at index 0 of array
$scope.myOnceOnlyFunction(maps); // pass the map to your function
});
也可以遍历instances
数组来运行每个地图上的函数(如果你的页面中加载了多个地图):
uiGmapIsReady.promise() // this gets all (ready) map instances - defaults to 1 for the first map
.then(function(instances) { // instances is an array object
angular.forEach(instances, function(value, key) {
var maps = value.map;
$scope.myOnceOnlyFunction(maps); // will apply this function to each map
});
});
所以整个控制器看起来像
myApp.controller('MainCtrl', function($scope, uiGmapGoogleMapApi, uiGmapIsReady) {
uiGmapGoogleMapApi
.then(function(maps){
$scope.googlemap = {};
$scope.map = {
center: {
latitude: 37.7749295,
longitude: -122.4194155
},
zoom: 13,
pan: 1,
options: myAppServices.getMapOptions().mapOptions,
control: {},
events: {
tilesloaded: function (maps, eventName, args) {
},
dragend: function (maps, eventName, args) {
},
zoom_changed: function (maps, eventName, args) {
}
}
};
});
uiGmapIsReady.promise() // this gets all (ready) map instances - defaults to 1 for the first map
.then(function(instances) { // instances is an array object
var maps = instances[0].map; // if only 1 map it's found at index 0 of array
$scope.myOnceOnlyFunction(maps); // this function will only be applied on initial map load (once ready)
});
$scope.myOnceOnlyFunction = function(maps){ // this will only be run once on initial load
var center = maps.getCenter(); // examples of 'map' manipulation
var lat = center.lat();
var lng = center.lng();
alert('I\'ll only say this once ! \n Lat : ' + lat + '\n Lng : ' + lng);
};
});
...不确定为什么常见问题解答中没有提及:'How do I access the map instance?' - 或者为什么建议使用tilesloaded
(which is thought to be unreliable)代替idle
或uiGmapIsReady
......?
也许FAQ问题真的是“ 我如何持续访问地图 ”?
答案 1 :(得分:1)
正如Sal Niro
指出另一个答案 - 绕过常量调用tilesloaded
或idle
的一个选项是定义一个变量,然后在第一次将其标记为真时events
个函数运行。
在控制器内初始地图加载后,API没有方法可以访问地图对象,这有点神奇和令人惊讶......但它确实有效。
然而 - 添加此答案,因为将整个控制器置于某个功能(或条件)中是不切实际的 - 并且您可能有一些功能想要被连续召唤。因此,只需定义一次&#39;运行一次&#39;在调用地图之前,在控制器中变量 。
<强>解决方案强>:
将变量(此处任意称为&#34; initialMapLoad&#34;)设置为false
或0
:
var initialMapLoad = 0
然后,在您的Google地图事件定义(例如tilesloaded
,dragend
或idle
)中,您可以在条件内放置您只想运行一次的函数:
if(initialMapLoad === 0) {
my_single_run_function();
var initialMapLoad = 1
}
在您的功能运行后,不要忘记将initialMapLoad
变量重新定义为1
或true
。
示例:强>
myApp.controller('MainCtrl', function($scope, uiGmapGoogleMapApi) {
var initialMapLoad = 0;
uiGmapGoogleMapApi
.then(function(maps){
$scope.map = {
center: {
latitude: 37.7749295,
longitude: -122.4194155
},
zoom: 13,
events: {
tilesloaded: function (maps, eventName, args) {
// functions that run every time
alert('I say this after every tile load');
if(initialMapLoad === 0){
// functions that run only once
alert('I only say this once' + maps.getBounds());
initialMapLoad = 1;
}
},
}
};
})
});
中的工作示例