2016-03-29 19 views
7

Supponiamo che io ho una pagina singola applicazione (angolare applicazione JS), e traggo un'istanza Google Map su un elemento id googleMap -esempio Riutilizzo delle API di Google Maps su pagina singola Applicazione

var mapInstance = new google.maps.Map(document.getElementById(`googleMap`), mapOption) 

quindi a navigare attraverso il routing dell'applicazione, a causa di ciò, distrugge l'elemento DOM googleMap e infine torno alla rotta con questo elemento, ora devo ridisegnare la mappa su questo elemento.

Qual è il modo corretto per ridisegnare la mappa?

Come ho letto in this answer non è necessario ricrearlo, ma utilizzare la stessa istanza.

risposta

3

Questa domanda ha il tag angularjs quindi presumo che si tratti di un'applicazione Angular JS. In tal caso, probabilmente non dovresti farlo nel tuo controller di pagina.

È possibile utilizzare una direttiva preesistente come https://angular-ui.github.io/angular-google-maps/#!/ oppure è possibile scrivere la propria direttiva.

Se si scrive la propria direttiva, è necessario distruggere l'istanza di google map ogni volta che la direttiva viene distrutta utilizzando l'evento $ scope.on ('$ destroy', fn). Ti piace questa ..

$scope.on('$destroy', function(){ 
    mapInstance = null; 
}) 
+0

yeap, è angolare applicazione JS – URL87

+0

In un caso scrivo la mia direttiva, che cosa devo fare in la funzione '$ destroy' e come ridisegnarla? – URL87

+0

Ho aggiornato la mia risposta su come distruggerlo.Non sono sicuro del motivo per cui è necessario ridisegnarlo poiché il DOM a cui è collegato è scomparso. Basta creare una nuova mappaInstance quando viene compilata la nuova direttiva. – jonhobbs

2

Starei attento con

$scope.on('$destroy', function(){ 
    mapInstance = null; 
}) 

ho avuto una direttiva che contiene la mia mappa elemento DOM, e stava chiamando questo metodo per rimuovere tutti i riferimenti della mappa dalla dataLayer, tutti gli ascoltatori, e quindi impostando la mappa su null. Stavo controllando l'heap tra la navigazione della pagina e l'istanza della mappa era stata creata di nuovo, ma le vecchie mappe erano ancora nell'heap che portava ad un utilizzo sempre maggiore della memoria.

Anche la risposta che hai collegato raccomanda di riutilizzare l'istanza della mappa invece di provare a rimuoverla. Anche gli sviluppatori di google maps raccomandano questo approccio. La soluzione che ho trovato è stata quella di passare l'elemento direttiva a un servizio e aggiungere un elemento figlio a quello che creava la mappa sul nuovo elemento figlio. Se la mappa esiste già, basta aggiungere la mappa div all'elemento della direttiva. Ecco il mio codice qui sotto.

ng-view Elemento

<map-container></map-container> 

direttiva

angular.module('project') 
    .directive('mapContainer', function($timeout, mapService) { 
    return { 
     template: '<div></div>', 
     restrict: 'E', 
     replace: true, 
     link: function(scope, element) { 
     $timeout(function() { 
      //Use the $timeout to ensure the DOM has finished rendering 
      mapService.createMap(element).then(function() { 
       //map now exists, do whatever you want with it 
      }); 
     }); 
     } 
    }; 
}) 

Servizio

angular.module('project') 
    .service('mapService', function($q) { 

    var lat = -33.1798; 
    var lng = 146.2625; 
    var minZoom = 5; 
    var maxZoom = 20; 
    var zoom = 6; 
    var mapOptions = null; 
    var map = null; 

    function initialiseGmap(element) { 

     return $q(function (resolve) { 
     if (map) { 
      //Map already exists, append it 
      element.append(map.getDiv()); 
      resolve(); 
     } else { 
      //No map yet, create one 
      element.append('<div id="map_canvas"></div>'); 

      mapOptions = { 
      zoom: zoom, 
      center: new google.maps.LatLng(lat, lng), 
      styles: hybridMap, //your style here 
      minZoom: minZoom, 
      maxZoom: maxZoom, 
      mapTypeId: google.maps.MapTypeId.ROADMAP, 
      mapTypeControl: false, 
      streetViewControl: false, 
      panControl: false, 
      scaleControl: true, 
      zoomControl: false 
      }; 

      map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions); 

      //create any map listeners you want here. If you want to add data to the map and add listeners to those, I suggest a seperate service. 

      resolve(); 
     } 
     }); 
    } 

    return { 
     createMap: function(elem) { 
     return initialiseGmap(elem); 
     }, 
     getMap: function() { 
     return map; 
     }, 
     //Create as many functions as you like to interact with the map object 
     //depending on our project we have had ones to interact with street view, trigger resize events etc etc. 
     getZoom: function() { 
     return zoom; 
     }, 
     setZoom: function(value) { 
     map.setZoom(zoom); 
     } 
    }; 
    }); 
0

Nel mio caso ha contribuito a ri-init l'ializzazione di Google Map con timeout ha risolto il problema.

setTimeout(function(){ initialize() }, 30); 

Uccidere esempio inizializzato possibile distruggendo elemento creato in precedenza in modo dinamico, ma questo è più difficile ...

Problemi correlati