2012-06-24 11 views
27

Ich überlege, von Backbonejs in AngularJs zu migrieren.Google Map in AngularJS initialisieren

Im Backbone kann ich eine Ansicht initialisieren, an welcher Stelle ich eine Instanz von Google Map erstelle. Ich kann dann schwenken/zoomen/etc und zwischen Ansichten wechseln und nicht den aktuellen Zustand der Karte verlieren.

Angesichts der folgenden mit AngularJS:

layout.html

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

map.html

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

Ich war in der Lage, eine Richtlinie erstellen eine Karte nur gut zu machen. Problem ist, dass es die Karte jedes Mal neu lädt, wenn ich zurück zur Kartenansicht wechsle.

<map></map> 

Also von dem, was ich über Angular lerne, dachte ich, ich MapController schaffen würde und die Karte dort initialisieren. Kein Erfolg.

Fazit ist, dass ich eine Google-Karte async-init initiieren und Daten lokal oder remote dorthin schieben UND in der Lage sein, die App ohne RELOADING die Karte von Grund auf jedes Mal zu navigieren.

Kann jemand den richtigen Ansatz vorschlagen?

Danke :)

Versuch Pro Andy Joslin Vorschlag:

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

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> 

ich Fehler: Unbekannter Anbieter: GoogleMapsProvider < - Google

+0

+1. Möchte auch die Antwort wissen. –

+1

Ich habe ein Projekt [eckig-google-maps] (https://github.com/LarryEitel/angular-google-maps) mit laufenden Verbesserungen erstellt. Siehe [Live-Version] (http://angular-google-maps.nodester.com/) –

+0

Großartig, bereits auf meiner Beobachtungsliste. :) –

Antwort

18

Seit Ansichten erstellen und Zerstöre Controller, wenn sich die Ansicht ändert, du willst deine Maps dat a, um woanders zu bestehen. Versuchen Sie, einen GoogleMap-Dienst zu erstellen, der die Daten speichert.

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

Wenn Ihnen diese Lösung nicht gefällt, gibt es auch andere Möglichkeiten.

+0

Können Sie kurz die anderen Optionen skizzieren (nur benennen)? Vielen Dank. –

+2

Sie könnten die Map in $ rootScope erstellen, die niemals zerstört wird und untergeordnete Bereiche erben. Sie könnten auch nicht ng-view verwenden, damit die Bereiche und dom-Elemente nicht zerstört werden, sondern stattdessen ein- und ausgeblendet werden, aber Sie müssten Ihr eigenes Routing-System rollen. Sie könnten auch ein Karten-Ding erstellen, das nur ein einfaches altes JavaScript-Objekt außerhalb des Winkels ist, auf das sich Ihre Winkelsteuergeräte beziehen (aber das ist wirklich nur eine schlechte Art, einen Dienst zu machen) –

+0

Andy, Sehr nett von Ihnen, einige Ideen vorzuschlagen. Ich bin bei Angular so grün. Gibt es eine Chance, dass du ein Beispiel aushecken kannst? Ich stecke im Schlamm fest und wirbele meine Räder. Danke :) –

1

Das ist, was ich in Backbone mache, um die Ansicht zu behalten, anstatt sie zu zerstören. Angenommen, Sie haben ein div mit id = "container" und Ihr Router hat die entsprechenden Routen.

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

Vielen Dank Jerry, aber Ihre Lösung ist im Backbone eher als angularjs. –

0

Hier ist meine Lösung, um die Karten api mit AngularJS routeProvider für die Anwendung: in Ihrem Index müssen Sie hinzufügen:

Winkel google-maps.min.js und 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" 
    }); 

}); 

})();

nicht zuletzt in Ihrem 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

Hallo Larry Eitel und alle, ich habe folgendes Vorgehen:

Zuerst müssen wir einige globale Variablen erstellen:

var mapGlobal, flag=0, CurrentmapNode; 

Dann in 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 
    }); 

} 

Der " on destroy "Funktion speichert den aktuellen Kartenstatus in einer anderen globalen Variablen. Wenn die Ansicht neu erstellt wird, müssen wir keine weitere Karteninstanz erstellen.

Das Erstellen einer anderen Karteninstanz kann zu einem Speicherverlust führen und die Verwendung der Google Maps-API jedes Mal erhöhen, wenn die Ansicht neu erstellt wird.

Mit freundlichen Grüßen