5

Теперь, когда я нашел способ инициализировать Карты Google с помощью Andy Joslin в этом SO initialize-google-map-in-angularjs, я ищу способ асинхронной загрузки объекта Google Map.Как асинхронно загружать карту google в 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']); 
    }); 

Когда я делаю это и пойти, чтобы загрузить Карта страницы я получаю:

A call to document.write() from an asycrononously-loaded 
external script was ignored. 

Это как Google Maps загружается в настоящее время в качестве услуги:

'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); 
} 

Похоже, что это должно возвращать обещание от того, что я помню. Но этот AngularJS для меня очень новый.

+0

Для продвигайте продвижение по этому вопросу. Я создал проект git здесь: https://github.com/LarryEitel/angular-google-maps И нажал его здесь: http://angular-google-maps.nodester.com/. Я начал тему в Google Groups по этому адресу: https://groups.google.com/forum/?fromgroups&nomobile=true#!topic/angular/CM8ewcWeTF4 –

+0

Когда вы загружаете библиотеку API Карт асинхронно, вы должны * предоставить callback с параметром 'callback =' query. В противном случае загрузчик API будет использовать 'document.write()', который не работает из асинхронного вызова. Мини-библиотека в ответе [GFoley83] (http://stackoverflow.com/a/17396353/1202830) добавляет этот параметр для вас, поэтому он может работать в такой асинхронной ситуации загрузки. –

ответ

5

Если вы используете JQuery в приложении AngularJS, проверить эту функцию, которая возвращает promise для когда API Карт Google был загружен:

https://gist.github.com/gbakernet/828536

Я был в состоянии использовать это в AngularJS директиве ленивая загрузка Google Maps по требованию. Работает лакомство:

angular.module('mapModule') // usage: data-google-map 
    .directive('googleMap', ['$window', function ($window) { 
     return { 
      restrict: 'A', 
      link: function (scope, element, attrs) { 
       // If Google maps is already present then just initialise my map 
       if ($window.google && $window.google.maps) { 
        initGoogleMaps(); 
       } else { 
        loadGoogleMapsAsync(); 
       } 

       function loadGoogleMapsAsync() { 
        // loadGoogleMaps() == jQuery function from https://gist.github.com/gbakernet/828536 
        $.when(loadGoogleMaps()) 
         // When Google maps is loaded, add InfoBox - this is optional 
         .then(function() { 
          $.ajax({ url: "/resources/js/infobox.min.js", dataType: "script", async: false }); 
         }) 
         .done(function() { 
          initGoogleMaps(); 
         }); 
       }; 

       function initGoogleMaps() { 
        // Load your Google map stuff here 
        // Remember to wrap scope variables inside `scope.$apply(function(){...});` 
       } 
      } 
     }; 
    }]); 
+9

Eek, смешанный угловой и jQuery! –

+1

@ Свекла-Свекла Станьте своей задницей, я сделал! В настоящее время нет простого способа загрузить скрипты с помощью AngularJS, и API Карт Google не поддерживает обещания изначально. Я предложил более чем адекватное решение; если у вас есть лучший, тогда посмотрим! :) – GFoley83

+0

GFoley, я беру вашу точку зрения, и я не сказал, что это не рационально, я просто сказал «eek». Я не пробовал, но может ли AngularJS $ q не принуждать jQuery обещать в свои права в соответствии с Q.js? Если это так, то в 'loadGoogleMapsAsync()' все, кроме выражения '$ .ajax (...)', могут быть записаны с помощью $ q, что представляется более подходящим в модуле Angular.js. –

7

Вот мое решение, которое я придумал, не используя 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'); 
        }); 
       } 
      } 
     }; 
    }]); 
2

Взгляните это я считаю его более надежным

var deferred = $q.defer(); 
         var script = document.createElement('script'); 

         $window.initMap = function() { 
          //console.log("Map init "); 

          deferred.resolve(); 
         } 
         script.src = "//maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places&callback=initMap"; 
         document.body.appendChild(script); 
         return deferred.promise;