2012-06-24 9 views
27

Rozważam migrację z backbonejs do angularjs.Inicjuj mapę Google w AngularJS

W kręgosłupie mogę zainicjować widok, w którym momencie tworzę instancję mapy google. Mogę wtedy przesuwać/powiększać/etc i przełączać się między widokami i nie tracić aktualnego stanu mapy.

Przy następujących wykorzystujące angularjs:

layout.html

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

map.html

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

udało mi się stworzyć dyrektywę do renderowania map dobrze. Problem polega na tym, że ponownie ładuje mapę za każdym razem, gdy przełączę się z powrotem do widoku mapy.

Z tego, czego się dowiedziałem o Angular, pomyślałem, że utworzę MapController i zainicjuję tam mapę. Bez powodzenia.

Najważniejsze jest to, że muszę asyncować -inicjować mapę google i przesyłać dane do niej lokalnie lub zdalnie. I móc poruszać się po aplikacji bez odkładania mapy od początku za każdym razem.

Czy ktoś może zaproponować prawidłowe podejście?

Dziękuję :)

Próba Per Andy Joslin sugestia:

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

W services.js:

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

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

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

W map.html

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

otrzymuję błąd: Unknown provider: GoogleMapsProvider < - GoogleMaps

+0

+1. Chciałbym również znać odpowiedź. –

+1

Stworzyłem projekt [angular-google-maps] (https://github.com/LarryEitel/angular-google-maps) z ciągłymi ulepszeniami. Zobacz [wersja na żywo] (http://angular-google-maps.nodester.com/) –

+0

Świetnie, już na mojej liście obserwowanych. :) –

Odpowiedz

18

Ponieważ poglądy i tworzyć niszcz kontrolery, gdy widok się zmienia, chcesz datować mapy przetrwać gdzie indziej. Spróbuj utworzyć usługę GoogleMap, która będzie przechowywać dane.

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

Jeśli nie podoba ci się to rozwiązanie, istnieją również inne sposoby, aby to zrobić.

+0

Czy możesz krótko zarysować inne opcje (po prostu nazywając je)? Dziękuję Ci. –

+2

Można utworzyć mapę w $ rootScope, która nigdy nie jest niszczona, a jej zakresy potomne dziedziczą. Nie można również użyć widoku Ng, więc zakresy i elementy domena nie są tworzone jako zniszczone, ale zamiast tego są pokazywane i ukrywane, ale trzeba byłoby przetasować własny system routingu. Można również utworzyć obiekt mapy, który jest po prostu zwykłym starym obiektem JavaScript spoza kątów, o którym wspominają kontrolerzy kątów (ale jest to po prostu kiepski sposób wykonania usługi). –

+0

Andy, Bardzo miło z twojej strony, że możesz zasugerować kilka pomysłów. Jestem taki zielony w Angular. Czy możesz podać swój przykład? Utknąłem w błocie i obracałem koła. Dziękuję :) –

1

To właśnie robię w kręgosłupie, aby zachować widok zamiast go niszczyć. Załóżmy, że masz element div o id = "container", a router ma odpowiednie trasy.

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

Dziękuję Jerry, ale twoje rozwiązanie jest w kręgosłupie, a nie angularjs. –

0

Oto moje rozwiązanie za pomocą API mapy z angularjs routeProvider: w indeksie trzeba dodać:

kątowe-google-maps.min.js i lodash.min.js

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

}); 

})();

Ostatni, ale nie najmniej w kontrolerze:

(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 i wszyscy, mam następujące podejście:

pierwsze, musimy utworzyć niektóre zmienne globalne:

var mapGlobal, flag=0, CurrentmapNode; 

Następnie w 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 
    }); 

} 

The " on destroy "zapisuje bieżący stan mapy w innej zmiennej globalnej, a po odtworzeniu widoku nie musimy tworzyć kolejnej instancji mapy.

Utworzenie kolejnej instancji mapy może spowodować wyciek pamięci i zwiększyć użycie interfejsu Google Maps API przy każdym odtworzeniu widoku.

Pozdrawiam