我正在尝试在Angular / IonicFramework中实现Google地图。我正在使用指令,服务和控制器。我在$scope
中有一个地图,标记和地理位置对象。视图中的地图对象和标记对象将从服务更新,但地理位置对象不会更新。
模板/视图:
<div class="item item-input item-stacked-label item-icon-right">
<div>
Location
<a ng-click="centerOnMe()">
<i class="icon ion-android-locate" style="font-size:24px"></i>
</a>
</div>
<textarea style="margin-top: 0px; margin-bottom: 0px; height: 45px;" placeholder="Location not found." disabled>{{geoloc.addr}}</textarea>
</div>
<div class="item item-input">
<div class="input-label">Map</div>
</div>
<div class="item item-input" style="height:15em;">
<ion-content scroll="false">
<map on-create="mapCreated(map, geoloc, marker)"></map>
</ion-content>
</div>
地图指令:
angular.module('starter.directives', [])
.directive('map', function(MapService) {
return {
restrict: 'E',
scope: {
onCreate: '&'
},
link: function ($scope, $element, $attr) {
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(43.07493, -89.381388),
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map($element[0], mapOptions);
var geoloc = {
lat: null, lng: null, str: null, brgy: null,
muni: null, reg: null, addr: null
};
var marker = new google.maps.Marker({
map: map
});
$scope.onCreate(
{
map: map, //link map to map in controller
geoloc: geoloc, //link geoloc to geoloc in controller
marker: marker //link marker to marker in controller
});
// Stop the side bar from dragging when mousedown/tapdown on the map
google.maps.event.addDomListener($element[0], 'mousedown', function (e) {
e.preventDefault();
return false;
});
}
if (document.readyState === "complete") {
initialize();
} else {
google.maps.event.addDomListener(window, 'load', initialize);
}
}
}
});
地图控制器:
angular.module('starter.controllers', [])
.controller('MapCtrl', function($scope, $ionicLoading, MapService) {
$scope.mapCreated = function(map, geoloc, marker) {
$scope.map = map; //sets the map from the directive to the $scope
$scope.geoloc = geoloc; //sets the geoloc from the directive to the $scope
$scope.marker = marker; //sets the marker from the directive to the $scope
};
$scope.centerOnMe = function () {
console.log('Centering..');
if (!$scope.map && !$scope.marker && !$scope.geoloc) {
return;
}
$scope.loading = $ionicLoading.show({
template: 'Getting current location...',
noBackdrop: true
});
$scope.geoloc = MapService.getCurrentLocation($ionicLoading, $scope.map, $scope.geoloc, $scope.marker);
// ^^^ This doesn't seem to work. $scope.geoloc doesn't get updated immediately, while $scope.map and $scope.marker gets updated immediately. Has to be invoked twice for $scope.geoloc to be updated.
}
});
地图服务:
angular.module('starter.services', [])
.factory('MapService', function() {
return {
getCurrentLocation: function($ionicLoading, map, geoloc, marker) {
navigator.geolocation.getCurrentPosition(function (pos) { //callback if get location succeeds
geoloc.lat = pos.coords.latitude;
geoloc.lng = pos.coords.longitude;
var latlngpos = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'latLng': latlngpos}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
map.setZoom(16);
marker.setOptions({
position: latlngpos,
map: map
});
geoloc.str = results[0].address_components[0].short_name; //type:route
geoloc.brgy = results[0].address_components[1].short_name; //type:neighborhood
geoloc.muni = results[0].address_components[2].short_name; //type:locatlity
geoloc.reg = results[0].address_components[3].short_name; //type:admnistrative_area_level_1
geoloc.addr = results[0].formatted_address;
} else {
console.log('No results found');
}
} else {
console.log('Geocoder failed due to: ' + status);
}
});
map.setCenter(latlngpos);
$ionicLoading.hide();
}, function (error) { //callback if get location fails
alert('Unable to get location: ' + error.message);
});
return geoloc;
}
}
})
;
我的实施基于此:
http://www.jeffvandalsum.com/integrating-google-maps-api-with-angular/
我已按照此处建议的解决方案,但$scope.geoloc
对象仍未更新:
Angular directive scope between google maps and a controller
Phonegap not firing GoogleMaps v3 domListener function inside Angularjs directive
答案 0 :(得分:0)
尝试包装
$scope.geoloc = MapService.getCurrentLocation($ionicLoading,$scope.map, $scope.geoloc, $scope.marker);
$timeout
angular.module('starter.controllers', [])
.controller('MapCtrl', function($scope,$timeout, $ionicLoading, MapService) {
$scope.mapCreated = function(map, geoloc, marker) {
$scope.map = map; //sets the map from the directive to the $scope
$scope.geoloc = geoloc; //sets the geoloc from the directive to the $scope
$scope.marker = marker; //sets the marker from the directive to the $scope
};
$scope.centerOnMe = function () {
console.log('Centering..');
if (!$scope.map && !$scope.marker && !$scope.geoloc) {
return;
}
$scope.loading = $ionicLoading.show({
template: 'Getting current location...',
noBackdrop: true
});
$timeout(function(){
$scope.geoloc = MapService.getCurrentLocation($ionicLoading, $scope.map, $scope.geoloc, $scope.marker);
// ^^^ This doesn't seem to work. $scope.geoloc doesn't get updated immediately, while $scope.map and $scope.marker gets updated immediately. Has to be invoked twice for $scope.geoloc to be updated.
});
}
});
旁注:这不一定是最佳方式,但它应该会触发$scope.geoloc
来正确更新。
我还建议Gajotres's tutorial。
希望这有用!
答案 1 :(得分:0)
我刚刚重写了我的指令,服务和控制器,现在它正在工作。现在数据包含在服务中。然后我将服务注入指令和控制器。
地图服务:
.factory('MapService', function() {
var service = {};
service.map = null;
service.marker = null;
service.geoloc = {
lat: 0.0,
lng: 0.0,
str: "",
brgy: "",
muni: "",
reg: "",
addr: ""
};
service.init = function(map, marker) {
this.map = map;
this.marker = marker;
}
service.getCurrLoc = function($ionicLoading) {
navigator.geolocation.getCurrentPosition(function (pos) { //callback if get location succeeds
service.geoloc.lat = pos.coords.latitude;
service.geoloc.lng = pos.coords.longitude;
var latlngpos = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);
var geocoder = new google.maps.Geocoder();
service.marker = new google.maps.Marker({
position: latlngpos,
map: service.map
});
//get location
geocoder.geocode({'latLng': latlngpos}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
service.map.setZoom(16);
service.marker.setOptions({
position: latlngpos,
map: service.map
});
service.geoloc.str = results[0].address_components[0].short_name; //type:route
service.geoloc.brgy = results[0].address_components[1].short_name; //type:neighborhood
service.geoloc.muni = results[0].address_components[2].short_name; //type:locatlity
service.geoloc.reg = results[0].address_components[3].short_name; //type:admnistrative_area_leveservice
service.geoloc.addr = results[0].formatted_address;
service.map.setCenter(latlngpos);
$ionicLoading.hide(); //hide loading prompt
} else {
console.log('No results found');
}
} else {
console.log('Geocoder failed due to: ' + status);
}
});
},
function (error) { //callback if get location fails
},
{ enableHighAccuracy: true }); //geolocation options
}
return service;
})
地图指令:
.directive('map', ["MapService", function(MapService) {
return {
restrict: 'E',
scope: {
onCreate: '&'
},
link: function ($scope, $element, $attr) {
function initialize() {
var mapOptions = {
//set to Philippines
center: new google.maps.LatLng(14.6839606, 121.0622039),
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
MapService.map = new google.maps.Map($element[0], mapOptions);
MapService.marker = new google.maps.Marker({
map: MapService.map
});
$scope.onCreate(
{
map: MapService.map, //link map to map in controller
marker: MapService.marker, //link marker to marker in controller
geoloc: MapService.geoloc //link geoloc to geoloc in controller
}
);
// Stop the side bar from dragging when mousedown/tapdown on the map
google.maps.event.addDomListener($element[0], 'mousedown', function (e) {
e.preventDefault();
return false;
});
}
if (document.readyState === "complete") {
initialize();
} else {
google.maps.event.addDomListener(window, 'load', initialize);
}
}
}
}])
地图控制器:
.controller('MapCtrl', ["$scope", "$ionicLoading", "MapService", function($scope, $ionicLoading, MapService) {
$scope.mapCreated = function(map, marker, geoloc) {
$scope.map = map; //sets the map from the directive to the $scope
$scope.marker = marker; //sets the marker from the directive to the $scope
$scope.geoloc = geoloc; //sets the geoloc from the directive to the $scope
console.log('$scope.geoloc in $scope.mapCreated', $scope.geoloc);
$scope.centerOnMe();
};
$scope.centerOnMe = function () {
console.log("Centering");
if (!$scope.geoloc && !$scope.map && !$scope.marker) {
console.log($scope.map);
console.log($scope.marker);
console.log($scope.geoloc);
return;
}
$scope.loading = $ionicLoading.show({
template: 'Getting current location...',
noBackdrop: true
});
MapService.getCurrLoc($ionicLoading);
}
}])