Инициализировать карту Google в AngularJS
Я рассматриваю переход из backbonejs в angularjs.
В позвоночнике я могу инициализировать представление, в какой точке я создаю экземпляр карты google. Затем я могу панорамировать/увеличивать/etc и переключаться между представлениями, а не терять текущее состояние карты.
Учитывая следующее, используя 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 и инициализирую карту там. Нет успеха.
Нижняя строка: мне нужно асинхронно инициализировать карту google и нажимать на нее данные локально или удаленно И иметь возможность перемещаться по приложению, не переставляя карту с нуля каждый раз.
Может кто-нибудь предложить правильный подход?
Спасибо:)
Попытка на предложение Энди Хослина:
В 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;
}
});
В контроллерах .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 < - GoogleMaps
Ответы
Ответ 1
Поскольку представления создают и уничтожают контроллеры при изменении вида, вы хотите, чтобы ваши данные карт сохранялись где-то в другом месте. Попробуйте создать службу 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;
};
}
Если вам не нравится это решение, есть и другие способы сделать это.
Ответ 2
Это то, что я делаю в Backbone, чтобы сохранить представление вместо его уничтожения. Предположим, у вас есть div с id = "container", и ваш маршрутизатор имеет соответствующие маршруты.
routes: {
"":"home",
"map": "showMap"
},
showMap: function() {
$("#container").children().detach();
if(!this.mapView) {
this.mapView = new MapView();
this.mapView.render();
}
$("#container").html(this.mapView.el);
}
Ответ 3
Здесь мое решение для использования карт api с Angularjs routeProvider:
в вашем индексе вы должны добавить:
angular -google-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"
});
});
})();
Last Но не в последнюю очередь в вашем контроллере:
(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);
})();
Ответ 4
Привет Ларри Эйтель и все, у меня есть следующий подход:
Во-первых, нам нужно создать некоторые глобальные переменные:
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" сохраняет текущее состояние карты в другой глобальной переменной, а затем, когда представление воссоздано, нам не нужно создавать другой экземпляр карты.
Создание другого экземпляра карты может привести к утечке памяти и увеличению использования API карт Google каждый раз, когда будет воссоздан вид.
С наилучшими пожеланиями