AngularJS - 负载谷歌地图脚本异步的指令支持多地图 [英] AngularJS - load google map script async in directive for multiple maps
问题描述
目前我正在试图加载一个页面上的多个谷歌地图。
我不希望包括谷歌地图API的脚本到HTML code,因为我不想被加载脚本,除非地图是在当前页面做。
我希望我的映射到一个单一的指令,也将执行谷歌地图API的脚本懒加载内部调用。
I am currently trying to load multiple google maps on a single page. I don't want to include google map API script into the HTML code as I don't want the script to be loaded unless the maps are in the current page. I want my maps to be called inside a single directive that will also perform the google map API script lazy loading.
所以,我周围搜查和找到了解决办法的,我调整了一下,但我的问题是,它只是将加载一张地图而不是其他。
So I searched around and found a solution that I tweaked a bit, but my problem is that it will only load one map but not the others.
我的HTML如下:
<div id="mapParis" class="google-map" lat="48.833" long="2.333"></div>
<div id="mapWashington" class="google-map" lat="38.917" long="-77.000"></div>
<div id="mapTokyo" class="google-map" lat="35.667" long="139.750"></div>
和指令:
// Google Map
app.directive('googleMap', ['$window', '$q', function( $window, $q ) {
function loadScript() {
console.log('loadScript');
// use global document since Angular's $document is weak
var s = document.createElement('script');
s.src = '//maps.googleapis.com/maps/api/js?sensor=false&language=en&callback=initMap';
document.body.appendChild(s);
}
// Lazy loading of the script
function lazyLoadApi(key) {
console.log('lazyLoadApi');
var deferred = $q.defer();
$window.initMap = function () {
deferred.resolve();
};
if ( $window.attachEvent ) {
$window.attachEvent('onload', loadScript);
} else {
$window.addEventListener('load', loadScript, false);
}
return deferred.promise;
}
return {
restrict: 'C', // restrict by class name
scope: {
mapId: '@id', // map ID
lat: '@', // latitude
long: '@' // longitude
},
link: function($scope, elem, attrs) {
// Check if latitude and longitude are specified
if ( angular.isDefined($scope.lat) && angular.isDefined($scope.long) ) {
console.log('-----');
// Initialize the map
$scope.initialize = function() {
console.log($scope.mapId);
$scope.location = new google.maps.LatLng($scope.lat, $scope.long);
$scope.mapOptions = {
zoom: 6,
center: $scope.location
};
$scope.map = new google.maps.Map(document.getElementById($scope.mapId), $scope.mapOptions);
new google.maps.Marker({
position: $scope.location,
map: $scope.map,
});
}
// Check if google map API is ready to run
if ( $window.google && $window.google.maps ) {
console.log('gmaps already loaded');
// Google map already loaded
$scope.initialize();
} else {
lazyLoadApi().then(function () {
// Promised resolved
console.log('promise resolved');
if ( $window.google && $window.google.maps ) {
// Google map loaded
console.log('gmaps loaded');
$scope.initialize();
} else {
// Google map NOT loaded
console.log('gmaps not loaded');
}
}, function () {
// Promise rejected
console.log('promise rejected');
});
}
}
}
};
下面是3张地图一的jsfiddle,你会看到,只有最后一个被加载:结果的http://的jsfiddle。净/ 5Pk8f / 1 /
Here is a jsFiddle with 3 maps, you will see that only the last one is loaded:
http://jsfiddle.net/5Pk8f/1/
我猜,我做错了什么与我的范围或承诺的处理方式,但我相当的想法,现在...
I guess that I am doing something wrong with my scope or the way the promise is handled, but I am quite out of ideas for now...
谢谢! (和对不起我的不是说好的英文)
Thanks! (and sorry for my not that good english)
作为更新
这里的完整的解决方案,我想出了:结果
http://jsfiddle.net/5Pk8f/5/
// Lazy loading of Google Map API
app.service('loadGoogleMapAPI', ['$window', '$q',
function ( $window, $q ) {
var deferred = $q.defer();
// Load Google map API script
function loadScript() {
// Use global document since Angular's $document is weak
var script = document.createElement('script');
script.src = '//maps.googleapis.com/maps/api/js?sensor=false&language=en&callback=initMap';
document.body.appendChild(script);
}
// Script loaded callback, send resolve
$window.initMap = function () {
deferred.resolve();
}
loadScript();
return deferred.promise;
}]);
谷歌地图指示
// Google Map
app.directive('googleMap', ['$rootScope', 'loadGoogleMapAPI',
function( $rootScope, loadGoogleMapAPI ) {
return {
restrict: 'C', // restrict by class name
scope: {
mapId: '@id', // map ID
lat: '@', // latitude
long: '@' // longitude
},
link: function( $scope, elem, attrs ) {
// Check if latitude and longitude are specified
if ( angular.isDefined($scope.lat) && angular.isDefined($scope.long) ) {
// Initialize the map
$scope.initialize = function() {
$scope.location = new google.maps.LatLng($scope.lat, $scope.long);
$scope.mapOptions = {
zoom: 12,
center: $scope.location
};
$scope.map = new google.maps.Map(document.getElementById($scope.mapId), $scope.mapOptions);
new google.maps.Marker({
position: $scope.location,
map: $scope.map,
});
}
// Loads google map script
loadGoogleMapAPI.then(function () {
// Promised resolved
$scope.initialize();
}, function () {
// Promise rejected
});
}
}
};
}]);
HTML使用样品
<div id="mapParis" class="google-map" lat="48.833" long="2.333"></div>
<div id="mapWashington" class="google-map" lat="38.917" long="-77.000"></div>
<div id="mapTokyo" class="google-map" lat="35.667" long="139.750"></div>
再次感谢maurycy
Thanks again to maurycy
推荐答案
您在这里有承诺和初始化一个问题,我将它清洗剂为你
you have a problem here with promises and initialisation, i've made it cleaner for you
显然,的jsfiddle已使这里移除工作plunker:的http:// plnkr .CO /编辑/ 1NpquJ?p = preVIEW
Apparently the jsfiddle has been removed so here is working plunker: http://plnkr.co/edit/1NpquJ?p=preview
这里是延迟加载GMaps实现服务
here is a service for lazy load gmaps
app.service('lazyLoadApi', function lazyLoadApi($window, $q) {
function loadScript() {
console.log('loadScript')
// use global document since Angular's $document is weak
var s = document.createElement('script')
s.src = '//maps.googleapis.com/maps/api/js?sensor=false&language=en&callback=initMap'
document.body.appendChild(s)
}
var deferred = $q.defer()
$window.initMap = function () {
deferred.resolve()
}
if ($window.attachEvent) {
$window.attachEvent('onload', loadScript)
} else {
$window.addEventListener('load', loadScript, false)
}
return deferred.promise
});
然后指令做它应该做的,只工作地图,不加载任何其他逻辑js文件
then the directive does what it should do, work only with map, don't load js files on any other logic
这篇关于AngularJS - 负载谷歌地图脚本异步的指令支持多地图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!