2012-06-24 57 views
27

我正在考慮從backbonejs移植到angularjs。在AngularJS中初始化Google Map

骨幹中,我能夠初始化一個視圖,在這一點上我創建了一個谷歌地圖的實例。然後,我可以平移/縮放/等,並在視圖之間切換,而不會丟失地圖的當前狀態。

考慮以下使用angularjs:

的layout.html

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

map.html

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

我能創造一個指令呈現地圖就好了。問題在於,每當我切換回地圖視圖時,它都會重新加載地圖。

<map></map> 

所以從我對Angular的學習中,我想我會創建一個MapController並初始化那裏的地圖。沒有成功。

底線是我需要async-init一個谷歌地圖,並將數據推送到本地或遠程,並且能夠導航應用程序,而無需每次從頭開始重新貼圖。

有人可以建議正確的做法嗎?

謝謝:)

嘗試每安迪喬斯林建議:

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

在services.js:

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

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

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

在map.html

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

我得到錯誤:未知提供商:GoogleMapsProvider < - 谷歌地圖

+0

+1。也想知道答案。 –

+1

我創建了一個項目[angular-google-maps](https://github.com/LarryEitel/angular-google-maps)並持續改進。查看[live version](http://angular-google-maps.nodester.com/) –

+0

太好了,已經在我的觀察名單上了。 :) –

回答

18

由於意見創建和當視圖改變時破壞控制器,你想要你的地圖數據一個堅持到別的地方。嘗試創建一個將存儲數據的GoogleMap服務。

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

如果你不喜歡這個解決方案,還有其他一些方法可以做到。

+0

你能否簡要概述其他選項(只是命名它們)?謝謝。 –

+2

您可以在$ rootScope中創建映射,該映射永遠不會被銷燬,並且子範圍會繼承它。你也可以不使用ng-view,這樣scope和dom元素就不會被破壞,而是被顯示和隱藏,但是你必須推出你自己的路由系統。你也可以創建一個地圖的東西,它只是一個角度控制器引用的角度外的簡單的舊JavaScript對象(但這實際上只是一種很差的服務方式) –

+0

Andy,非常好的你提出一些想法。我在Angular很綠。有什麼機會可以列舉一個例子嗎?我陷入泥濘中,旋轉着我的輪子。謝謝:) –

1

這就是我在Backbone中所做的,以保持視圖而不是銷燬它。假設你有一個id爲「container」的div,你的路由器有相應的路由。

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

謝謝傑裏,但是,你的解決方案是在骨幹而不是angularjs。 –

0

下面是我對使用Google Maps API與Angularjs routeProvider解決方法:在你的索引 你必須添加:

角谷歌-maps.min.js 和lodash.min.js

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

}); 

})();

最後但並非最不重要的在你的控制器:

(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

喜拉里·艾特爾和大家,我有以下方法:

首先,我們需要創建一些全局變量:

var mapGlobal, flag=0, CurrentmapNode; 

然後在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 
    }); 

} 

的「 on destroy「函數將當前地圖狀態保存在另一個全局變量中,然後,當重新創建視圖時,我們不需要創建另一個地圖實例。

創建另一個地圖實例會導致內存泄漏,並在每次重新創建視圖時增加Google地圖API的使用。

致以問候