google-maps-api-3 - 如何在 AngularJS 中异步加载谷歌地图?

标签 google-maps-api-3 asynchronous angularjs lazy-loading angularjs-directive

现在我已经找到了一种在 Andy Joslin 的帮助下初始化 Google Maps 的方法。在这个 SO initialize-google-map-in-angularjs ,我正在寻找一种异步加载谷歌地图对象的方法。

我在 phonecat 中找到了如何执行此操作的示例。项目。

注意这个例子中 JS 文件是如何加载的:​​index-async.html

在加载到我的程序中的 Jade Scripts 部分中,我尝试了:

script(src='js/lib/angular/angular.js')
script(src='js/lib/script/script.min.js')

script
  $script([
    'js/lib/angular/angular-resource.min.js',
    'js/lib/jquery/jquery-1.7.2.min.js',
    'http://maps.googleapis.com/maps/api/js?key=AIzaSyBTmi_pcXMZtLX5MWFRQgbVEYx-h-pDXO4&sensor=false',
    'js/app.js',
    'js/services.js',
    'js/controllers.js',
    'js/filters.js',
    'js/directives.js',
    'bootstrap/js/bootstrap.min.js'
    ], function() {
      // when all is done, execute bootstrap angular application
      angular.bootstrap(document, ['ofm']);
    });

当我这样做并加载 map 页面时,我得到:
A call to document.write() from an asycrononously-loaded 
external script was ignored.

这就是现在将 Google map 作为服务加载的方式:
'use strict';

var app = angular.module('ofm.services', []);

app.factory('GoogleMaps', function() {

  var map_id  = '#map';
  var lat     = 46.87916;
  var lng     = -3.32910;
  var zoom    = 15;
  var map     = initialize(map_id, lat, lng, zoom);

  return map;
});

function initialize(map_id, lat, lng, zoom) {
  var myOptions = {
    zoom : 8,
    center : new google.maps.LatLng(lat, lng),
    mapTypeId : google.maps.MapTypeId.ROADMAP
  };
  return new google.maps.Map($(map_id)[0], myOptions);
}

看来这应该是从我记得读过的内容中返回的一个 promise 。但是这个 AngularJS 对我来说很新。

最佳答案

这是我在不使用 jQuery 的情况下提出的解决方案:
(Gist here)

angular.module('testApp', []).
    directive('lazyLoad', ['$window', '$q', function ($window, $q) {
        function load_script() {
            var s = document.createElement('script'); // use global document since Angular's $document is weak
            s.src = 'https://maps.googleapis.com/maps/api/js?sensor=false&callback=initialize';
            document.body.appendChild(s);
        }
        function lazyLoadApi(key) {
            var deferred = $q.defer();
            $window.initialize = function () {
                deferred.resolve();
            };
            // thanks to Emil Stenström: http://friendlybit.com/js/lazy-loading-asyncronous-javascript/
            if ($window.attachEvent) {  
                $window.attachEvent('onload', load_script); 
            } else {
                $window.addEventListener('load', load_script, false);
            }
            return deferred.promise;
        }
        return {
            restrict: 'E',
            link: function (scope, element, attrs) { // function content is optional
            // in this example, it shows how and when the promises are resolved
                if ($window.google && $window.google.maps) {
                    console.log('gmaps already loaded');
                } else {
                    lazyLoadApi().then(function () {
                        console.log('promise resolved');
                        if ($window.google && $window.google.maps) {
                            console.log('gmaps loaded');
                        } else {
                            console.log('gmaps not loaded');
                        }
                    }, function () {
                        console.log('promise rejected');
                    });
                }
            }
        };
    }]);

关于google-maps-api-3 - 如何在 AngularJS 中异步加载谷歌地图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11217002/

相关文章:

google-maps - Google map 中的地球 View

javascript - 何时使用 Promises 延迟函数

java - 具有阻塞应用程序的 Tomcat NIO 连接器

javascript - 清除输入时如何在angularjs中使用select2-removed of select2触发事件

angularjs - 与 Angularjs 和 Backbonejs 相比,Iron Router 如何呈现单页 Web 应用程序

tinymce - 集成 AngularJS 和tinyMCE

javascript - 每 x 秒更新一次谷歌地图上的标记

javascript - IE11 中的 Google map 给出 "Unspecified error"

internet-explorer - 自定义 SVG 标记不会在 IE 11 中显示

javascript - 从循环运行异步函数