5

Ora che ho trovato un modo per inizializzare Google Maps con l'aiuto di Andy Joslin in questo SO initialize-google-map-in-angularjs, sto cercando un modo per caricare asincronicamente un oggetto Mappa di Google.Come caricare in modo asincrono una mappa google in AngularJS?

Ho trovato un esempio di come farlo nel progetto phonecat.

Notate come i file JS vengono caricati in questo esempio: index-async.html

Nei miei script Jade parziali che viene caricato nel mio programma ho provato:

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

Quando faccio questo e vado a caricare il mappa pagina ottengo:

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

Questo è il modo di Google Maps viene caricato ora come un servizio:

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

Sembra che questo dovrebbe restituire una promessa da ciò che ricordo di aver letto. Ma questo AngularJS è molto nuovo per me.

+0

Per promuovere i progressi su questo ho creato un progetto git qui: https://github.com/LarryEitel/angular-google-maps E l'ho spinto live qui: http://angular-google-maps.nodester.com/. Ho iniziato una discussione su Google Gruppi al seguente indirizzo: https://groups.google.com/forum/?fromgroups&nomobile=true#!topic/angular/CM8ewcWeTF4 –

+0

Quando carichi la libreria API di Maps in modo asincrono, devi * fornire un funzione di callback con il parametro di query 'callback ='. Altrimenti il ​​loader API userà 'document.write()' che non funziona da una chiamata asincrona. La mini-libreria nella risposta [GFoley83] (http://stackoverflow.com/a/17396353/1202830) aggiunge questo parametro per te, ed è per questo che può funzionare in una situazione di caricamento asincrona come questa. –

risposta

5

Se si utilizza jQuery nel vostro AngularJS app, controlla la funzione che restituisce una promise per quando l'API di Google Maps è stato caricato:

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

sono stato in grado di utilizzare questo in una direttiva AngularJS caricare Google Maps su richiesta. funziona a meraviglia:

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, misto Angolare e jQuery! –

+1

@ Beetroot-Beetroot Scommetto che il tuo culo l'ho fatto! Attualmente non esiste un modo semplice per caricare script con AngularJS e l'API di Google Maps non supporta le promesse in modo nativo. Ho proposto una soluzione più che adeguata; se ne hai uno migliore allora fallo vedere! :) – GFoley83

+0

GFoley, prendo il tuo punto e non ho detto che non era razionale, ho appena detto "eek". Non ho provato, ma i $ q di AngularJS non possono forzare jQuery come promette a Q.js? Se è così, allora in 'loadGoogleMapsAsync()', tutto tranne l'espressione '$ .ajax (...)' può essere scritto con $ q, che sembra più appropriato in un modulo Angular.js. –

7

ecco la mia soluzione mi è venuta senza l'utilizzo di 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

Date un'occhiata di questo penso che sia più affidabile

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; 
Problemi correlati