2012-06-24 3 views
27

Sto considerando la migrazione da backbonejs a angularjs.Inizializza Google Map in AngularJS

In backbone sono in grado di inizializzare una vista in cui punto di creare un'istanza di google map. Posso quindi pan/zoom/etc e passare da una vista all'altra e non perdere lo stato attuale della mappa.

Dati i seguenti utilizzando angularjs:

layout.html

<body> 
    <div class="container-fluid" ng-view></div> 

map.html

<div id="map_canvas" ng-controller="MapCtrl"></div> 

sono stato in grado di creare una direttiva per rendere una mappa più che bene. Il problema è che ricarica la mappa ogni volta che torno alla visualizzazione mappa.

<map></map> 

Quindi, da quello che sto imparando circa angolare, ho pensato vorrei creare un MapController e inizializzare la mappa lì. Nessun successo.

La linea inferiore è che devo avviare async-init una mappa di google e spingere i dati ad esso localmente o in remoto E essere in grado di navigare l'app senza ricaricare la mappa da zero ogni volta.

Qualcuno può suggerire l'approccio corretto?

In app.js::

// Generated by CoffeeScript 1.3.3 
(function() { 
    "use strict"; 

    angular.module("ofm", ["ofm.filters", "GoogleMaps", "ofm.directives"]).config([ 
    "$routeProvider", "$locationProvider", function($routeProvider, $locationProvider) { 
     $routeProvider.when("/", { 
     templateUrl: "partials/home" 
     }).when("/map", { 
     templateUrl: "partials/map", 
     controller: MapCtrl 
     }).otherwise({ 
     redirectTo: "/" 
     }); 
     return $locationProvider.html5Mode(true); 
    } 
    ]); 

}).call(this); 

In services.js:

angular.module('GoogleMaps', []). 
    factory('wasMapInitialized', function() { 
    console.log("inside service"); 
    var maps = 0; 

    if (!maps) { 
     maps += 1; 
     return 0; 
    } else { 
     return 1; 
    } 
    }); 

voi :)

Tentativo Per Andy Joslin suggerimento Grazie

In controllers.js:

function MapCtrl($scope) { 
    if (!GoogleMaps.wasMapInitialized()) { 
    var lat = 46.87916; 
    var lng = -3.32910; 
    var map_id = '#map'; 
    initialize(map_id, lat, lng); 
    } 
    function initialize(map_id, lat, lng) { 
    var myOptions = { 
     zoom : 8, 
     center : new google.maps.LatLng(lat, lng), 
     mapTypeId : google.maps.MapTypeId.ROADMAP 
    }; 
    var map = new google.maps.Map($(map_id)[0], myOptions); 
    } 
} 

In map.html

#map 
<div ng-controller="MapCtrl"></div> 

ottengo l'errore: fornitore sconosciuto: GoogleMapsProvider < - GoogleMaps

+0

+1. Vorrei sapere anche la risposta. –

+1

Ho creato un progetto [angular-google-maps] (https://github.com/LarryEitel/angular-google-maps) con miglioramenti continui. Vedi [versione live] (http://angular-google-maps.nodester.com/) –

+0

Grande, già sulla mia lista di controllo. :) –

risposta

18

Dato vista creano e distruggi i controller quando la vista cambia, vuoi le tue mappe dat a persistere da qualche altra parte. Prova a creare un servizio GoogleMap che memorizzerà i dati.

myApp.factory('GoogleMaps', function() { 
    var maps = {}; 

    function addMap(mapId) { 
    maps[mapId] = {}; 
    } 
    function getMap(mapId) { 
    if (!maps[mapId]) addMap(mapId); 
    return maps[mapId]; 
    } 

    return { 
    addMap: addMap, 
    getMap: getMap 
    } 
}); 

function MyController($scope, GoogleMaps) { 
    //Each time the view is switched to this, retrieve supermanMap 
    $scope.map = GoogleMaps.getMap('supermanMap'); 

    $scope.editMap = function() { 
    $scope.map.kryptonite = true; 
    }; 
} 

Se non ti piace questa soluzione, ci sono altri modi per farlo anche tu.

+0

Potresti delineare brevemente le altre opzioni (solo nominandole)? Grazie. –

+2

È possibile creare la mappa in $ rootScope, che non viene mai distrutta e che gli ambiti figlio ereditano. Inoltre, non è possibile utilizzare ng-view in modo che gli ambiti e gli elementi dom non vengano creati distrutti, ma vengano invece mostrati e nascosti, ma è necessario eseguire il rollover del proprio sistema di routing. Potresti anche creare una cosa di mappe che è semplicemente un vecchio oggetto JavaScript esterno angolare che i tuoi controllori angolari fanno riferimento (ma questo è davvero solo un modo scadente di fare un servizio) –

+0

Andy, molto gentile da parte tua suggerirti qualche idea. Sono così verde ad Angular. Qualche possibilità di eliminare un esempio? Sono bloccato nel fango e gira le ruote. Grazie :) –

1

Questo è quello che sto facendo in Backbone per mantenere la vista invece di distruggerla. Supponiamo di avere un div con id = "container" e che il router abbia i percorsi corrispondenti.

routes: { 
    "":"home", 
    "map": "showMap" 
}, 

showMap: function() { 
    $("#container").children().detach(); 
    if(!this.mapView) { 
     this.mapView = new MapView(); 
     this.mapView.render(); 
    } 
    $("#container").html(this.mapView.el); 
} 
+1

Grazie Jerry tuttavia, la soluzione è in backbone piuttosto che angularjs. –

0

Ecco la mia soluzione per utilizzare l'API di Google Maps con Angularjs routeProvider: nell'indice bisogna aggiungere:

angolare-google-maps.min.js e lodash.min.js

in application.js:

(function() { 

var app = angular.module("myApp", ["ngRoute", "uiGmapgoogle-maps"]); 


app.config(function(uiGmapGoogleMapApiProvider) { 
    uiGmapGoogleMapApiProvider.configure({ 
     key: 'YOUR KEY HERE', 
     v: '3.17', 
     libraries: 'weather,geometry,visualization' 
    }); 
}); 

app.config(function($routeProvider) { 
    $routeProvider 
     .when("/home", { 
      templateUrl: "home.html", 
      controller: "HomeController" 
     }) 
     .when("/workwith", { 
      templateUrl: "workwith.html", 
      controller: "WorkwithController" 
     }) 




    .otherwise({ 
     redirectTo: "/home" 
    }); 

}); 

})();

Ultimo ma non meno importante nel controller:

(function() { 
var app = angular.module("myApp"); 
var MyController = function($scope, $http, $log, $location, $routeParams, uiGmapGoogleMapApi) { 
    $log.info("MyController"); 
    $log.info($routeParams); 

    // Define variables for our Map object 
    var areaLat = 44.2126995, 
     areaLng = -100.2471641, 
     areaZoom = 3; 

    uiGmapGoogleMapApi.then(function(maps) { 
     $scope.map = { 
      center: { 
       latitude: areaLat, 
       longitude: areaLng 
      }, 
      zoom: areaZoom 
     }; 
     $scope.options = { 
      scrollwheel: false 
     }; 
    });  
}; 
app.controller("MyController", MyController); 

})();

0

Hi Larry Eitel e tutti, ho il seguente approccio:

In primo luogo, abbiamo bisogno di creare alcune variabili globali:

var mapGlobal, flag=0, CurrentmapNode; 

Poi nel Controller:

function MapCtrl($scope) { 
    var lat = 46.87916; 
    var lng = -3.32910; 
    var map_id = '#map'; 

    if (flag==0) 
     initMap(mapId, lat, lng); 
    else 
     reinitMap(mapId); 

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

    if (typeof mapGlobal != 'undefined') 
     flag=1; 
    } 

    function reinitMap(mapId){ 
    $(mapId)[0].append(CurrentmapNode); 
    } 

    $scope.$on("$destroy", function(){ 
     CurrentmapNode = mapGlobal.getDiv(); //save current map in an auxiliar variable 
    }); 

} 

Il " on destroy "function salva lo stato corrente della mappa in un'altra variabile globale, quindi, quando viene ricreata la vista, non è necessario creare un'altra istanza della mappa.

La creazione di un'altra istanza di mappa può causare perdite di memoria e aumentare l'utilizzo dell'API di Google Maps ogni volta che viene ricreata la vista.

Cordiali saluti