AngularJS – 加载谷歌地图脚本async在多个地图的指令

前端之家收集整理的这篇文章主要介绍了AngularJS – 加载谷歌地图脚本async在多个地图的指令前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试在单个页面上加载多个Google地图。
我不想将谷歌地图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文件

猜你在找的Angularjs相关文章