我目前正在尝试在单个页面上加载多个Google地图。我不希望将Google Map API脚本包含到HTML代码中,因为我不希望加载脚本,除非地图位于当前页面中。我希望在一个指令中调用我的地图,该指令还将执行google map API脚本的延迟加载。
因此,我四处搜索,找到了需要稍作调整的解决方案,但是我的问题是它只会加载一张地图,而不会加载其他地图。
我的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 ://plnkr.co/edit/1NpquJ?p=preview(@maurycy plunker)
// 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 }); } } }; }]);
再次感谢maurycy
您在此处遇到关于诺言和初始化的问题,我已经为您做得更干净了
显然jsfiddle已被删除,因此这里工作正常:http ://plnkr.co/edit/1NpquJ?p=preview
这是延迟加载gmap的服务
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 });
然后该指令执行应做的工作,仅与map一起使用,不将js文件加载到任何其他逻辑上