5

Ahora que he encontrado una manera de inicializar Google Maps con la ayuda de Andy Joslin en este SO initialize-google-map-in-angularjs, estoy buscando una manera de cargar asincrónicamente un objeto Google Map.¿Cómo cargar asincrónicamente un mapa de Google en AngularJS?

Encontré un ejemplo de cómo hacerlo en el proyecto phonecat.

Observe cómo los archivos JS se cargan en este ejemplo: index-async.html

En mis guiones Jade parciales que se carga en mi programa Traté:

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

Cuando hago esto y voy a cargar el página del mapa me sale:

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

Así es como Google Maps se carga ahora como un servicio: 012

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

Parece que esto debería devolver una promesa por lo que recuerdo haber leído. Pero este AngularJS es muy nuevo para mí.

+0

Para promover el progreso en esto. Creé un proyecto de git aquí: https://github.com/LarryEitel/angular-google-maps Y lo presenté en vivo aquí: http://angular-google-maps.nodester.com/. Comencé un hilo en Grupos de Google aquí: https://groups.google.com/forum/?fromgroups&nomobile=true#!topic/angular/CM8ewcWeTF4 –

+0

Cuando carga la biblioteca de la API de Maps de forma asíncrona, * debe * proporcionar un función de devolución de llamada con el parámetro de consulta 'callback ='. De lo contrario, el cargador de la API usará 'document.write()' que no funciona desde una llamada asincrónica. La minibiblioteca en la respuesta [GFoley83] (http://stackoverflow.com/a/17396353/1202830) agrega este parámetro, por lo que puede funcionar en una situación de carga asincrónica como esta. –

Respuesta

5

Si el uso de jQuery en su AngularJS aplicación, echa un vistazo a esta función que devuelve un promise para cuando se ha cargado el API de Google Maps:

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

yo era capaz de utilizar esto en una directiva AngularJS para cargar perezosos Google Maps a pedido. trabaja un convite:

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, Angular mixto y jQuery! –

+1

@ Beetroot-Beetroot ¡Apuesta por el culo que hice! Actualmente no hay una manera fácil de cargar scripts con AngularJS y la API de Google Maps no admite promesas de forma nativa. He propuesto una solución más que adecuada; si tienes uno mejor, entonces vamos a verlo! :) – GFoley83

+0

GFoley, tomo su punto y no dije que esto no fuera racional, solo dije "eek". No lo he intentado pero ¿no puede AngularJS $ q no forzar las promesas de jQuery por sí mismo según Q.js? Si es así, en 'loadGoogleMapsAsync()', todas las expresiones menos la expresión '$ .ajax (...)' pueden escribirse con $ q, lo que parece más apropiado en un módulo Angular.js. –

7

aquí está mi solución que se me ocurrió sin usar 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

Tome un aspecto de este creo que es más fiable

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; 
Cuestiones relacionadas