【发布时间】:2014-06-04 19:44:25
【问题描述】:
如何在 angularjs 中使用 HTML5 地理位置?我可以使用 HTML5 获得它;但是如何将它传递给控制器中的 angularjs 范围?任何示例 jsfiddle 都会节省我的时间!
【问题讨论】:
标签: javascript angularjs angularjs-directive geolocation angularjs-scope
如何在 angularjs 中使用 HTML5 地理位置?我可以使用 HTML5 获得它;但是如何将它传递给控制器中的 angularjs 范围?任何示例 jsfiddle 都会节省我的时间!
【问题讨论】:
标签: javascript angularjs angularjs-directive geolocation angularjs-scope
我建议将其抽象为一个服务,这样您的控制器就不会依赖于 window.navigator,并避免不必要地使用 $scope.$apply()。这是我在项目中使用的:
angular.module('app', []).factory('geolocationSvc', ['$q', '$window', function ($q, $window) {
'use strict';
function getCurrentPosition() {
var deferred = $q.defer();
if (!$window.navigator.geolocation) {
deferred.reject('Geolocation not supported.');
} else {
$window.navigator.geolocation.getCurrentPosition(
function (position) {
deferred.resolve(position);
},
function (err) {
deferred.reject(err);
});
}
return deferred.promise;
}
return {
getCurrentPosition: getCurrentPosition
};
}]);
然后我像这样在我的控制器中使用它:
function captureUserLocation() {
geolocationSvc.getCurrentPosition().then(onUserLocationFound);
}
【讨论】:
deferred.resolve(position)) 解析的承诺,因此您的处理程序将是接收该数据的函数,例如onUserLocationFound(position) { ... }。如果你想处理地理定位错误,你会像任何其他承诺一样使用catch。
你可以做点什么
myApp.controller('fooCtrl', function($scope){
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position){
$scope.$apply(function(){
$scope.position = position;
});
});
}
})
您需要执行 $scope.$apply 以在地理位置到达时触发摘要循环并更新所有观察者。
【讨论】:
https,则不支持 navigator.geolocation!
您可以使用ngGeolocation。它很简单,并且可以完成工作。
angular.module('appName', ['ngGeolocation'])
.controller('appCtrl', function($scope, $geolocation) {
$geolocation.getCurrentPosition().then(function(position) {
console.log(position, 'current position');
});
});
【讨论】:
由于 Firefox 的问题是当用户单击“不现在”、X 或外部提示框 (more here) 时提示网站需要访问您的位置时没有收到用户的反馈,下面是一个触发后备操作的小示例这个案例。 Plunker
// GeoLocationService
angular.module('myApp').factory('GeoLocationService', function($q, $window, $timeout) {
var factoryObj = {};
factoryObj.getPosition = function() {
var deferred;
var promiseTimeout = $timeout(function() {
deferred.reject(1); // return 1 if browser waited for user input for more than timeout delay
}, 3000);
deferred = $q.defer();
if(!$window.navigator.geolocation) { // check if geoLocation is not supported by browser
$timeout.cancel(promiseTimeout);
deferred.reject(false); // return false if geoLocation is not supported
}
else { // geoLocation is supported
$window.navigator.geolocation.getCurrentPosition(function(position) {
$timeout.cancel(promiseTimeout);
return deferred.resolve(position);
}, function(error) {
$timeout.cancel(promiseTimeout);
return deferred.reject(error.code || 1);
});
}
return deferred.promise;
};
return factoryObj;
});
还有你的应用 js。
// App
var app = angular.module('myApp', []).controller('myCtrl', function($scope, $log, GeoLocationService) {
$scope.position = {};
GeoLocationService.getPosition().then(
function(position) { //
$scope.position = position;
$log.debug(position);
},
function(errorCode) {
if(errorCode === false) {
alert('GeoLocation is not supported by browser.');
}
else if(errorCode == 1) {
alert('User either denied GeoLocation or waited for long to respond.');
}
}
);
});
【讨论】: