我正在尝试在单个页面上加载多个Google地图。
我不想将谷歌地图API脚本包含在HTML代码中,因为我不希望加载脚本,除非地图位于当前页面。
我希望我的地图在一个单一的指令中被调用,这也将执行谷歌地图API脚本懒惰加载。
我不想将谷歌地图API脚本包含在HTML代码中,因为我不希望加载脚本,除非地图位于当前页面。
我希望我的地图在一个单一的指令中被调用,这也将执行谷歌地图API脚本懒惰加载。
所以我搜索和found a solution,我调整了一点,但我的问题是,它只会加载一个地图,而不是其他地图。
我的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.net/5Pk8f/1/
我想我做的事情我的范围或承诺的方式有问题,但我现在是很出于意见的想法…
谢谢! (对不起,我不是那么好的英文)
更新(回答后)
作为更新,
这里是我想出的完整解决方案:
http://jsfiddle.net/5Pk8f/5/
Google地图服务
// Lazy loading of Google Map API app.service('loadGoogleMapAPI',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地图指令
// 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,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,}); } // 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
你在这里承诺和初始化有一个问题,我已经使你更清洁了
显然jsfiddle已被删除,所以这里是工作的空间:http://plnkr.co/edit/1NpquJ?p=preview
JS
这里是一个延迟加载地图的服务
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',false) } return deferred.promise });
那么该指令会做什么,应该做什么,只使用map,不要在任何其他逻辑上加载js文件