2012-06-24 25 views
27

Estoy considerando migrar de backbonejs a angularjs.Inicializar Google Map en AngularJS

En la red troncal puedo inicializar una vista y en ese momento creo una instancia de google map. Puedo hacer un pan/zoom/etc. y cambiar de vista y no perder el estado actual del mapa.

Dadas las siguientes: AngularJS utilizando

layout.html

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

map.html

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

que fue capaz de crear una directiva para hacer un mapa muy bien. El problema es que vuelve a cargar el mapa cada vez que vuelvo a la vista del mapa.

<map></map> 

Así que de lo que estoy aprendiendo acerca angular, pensé que podría crear un MapController e inicializar el mapa allí. Sin éxito.

En resumen, necesito sincronizar e iniciar un mapa de Google y enviar datos a él localmente o de forma remota Y poder navegar por la aplicación sin volver a cargar el mapa desde cero cada vez.

¿Alguien puede sugerir el enfoque correcto?

Gracias :)

intento por Andy Joslin sugerencia:

En 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); 

En services.js:

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

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

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

En map.html

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

me sale error: proveedor de Desconocido: GoogleMapsProvider < - GoogleMaps

+0

+1. Me gustaría saber la respuesta también. –

+1

Creé un proyecto [angular-google-maps] (https://github.com/LarryEitel/angular-google-maps) con mejoras continuas. Ver [versión en vivo] (http://angular-google-maps.nodester.com/) –

+0

Genial, ya en mi lista de observación. :) –

Respuesta

18

Desde vistas a crear y Destruye los controladores cuando la vista cambia, quieres que tus mapas estén correctos un para persistir en otro lugar. Intenta crear un servicio de GoogleMap que almacenará los datos.

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

Si no te gusta esta solución, hay otras formas de hacerlo también.

+0

¿Podría resumir brevemente las otras opciones (simplemente nombrarlas)? Gracias. –

+2

Puede crear el mapa en $ rootScope, que nunca se destruye, y los alcances secundarios lo heredan. Tampoco puede usar ng-view para que los ámbitos y los elementos dom no se creen destruidos, sino que se muestren y oculten, pero tendrá que implementar su propio sistema de enrutamiento. También puede crear una cosa de mapas que es simplemente un objeto antiguo de JavaScript fuera de angular que sus controladores angulares hacen referencia (pero esta es realmente una manera pobre de hacer un servicio) –

+0

Andy, Muy amable de su parte sugerir algunas ideas. Estoy tan verde en Angular. ¿Alguna posibilidad de que reste un ejemplo? Estoy atascado en el barro y haciendo girar mis ruedas. Gracias :) –

1

Esto es lo que estoy haciendo en Backbone para mantener la vista en lugar de destruirla. Supongamos que tiene un div con id = "contenedor" y su enrutador tiene las rutas correspondientes.

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

Gracias Jerry, sin embargo, su solución está en la red troncal en lugar de angularjs. –

0

Aquí está mi solución para el uso de la API de mapas con AngularJS routeProvider: en el índice hay que añadir:

angular-google-maps.min.js y lodash.min.js

en 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" 
    }); 

}); 

})();

último, pero no menos en su controlador:

(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

Hola Larry Eitel y todo el mundo, tengo el siguiente enfoque:

En primer lugar, tenemos que crear algunas variables globales:

var mapGlobal, flag=0, CurrentmapNode; 

Luego, en 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 
    }); 

} 

El " función "destruir" guarda el estado del mapa actual en otra variable global, luego, cuando se recrea la vista, no es necesario crear otra instancia de mapa.

Crear otra instancia de mapa puede causar pérdida de memoria e incrementar el uso de la API de Google Maps cada vez que se vuelva a crear la vista.

Saludos cordiales