我有像
这样的服务app.factory('geolocation', function ($rootScope, cordovaReady) {
return {
getCurrentPosition: cordovaReady(function (onSuccess, onError, options) {
navigator.geolocation.getCurrentPosition(function () {
var that = this,
args = arguments;
if (onSuccess) {
$rootScope.$apply(function () {
onSuccess.apply(that, args);
});
}
}, function () {
var that = this,
args = arguments;
if (onError) {
$rootScope.$apply(function () {
onError.apply(that, args);
});
}
}, options);
}),
getCurrentCity: function (onSuccess, onError) {
this.getCurrentPosition(function (position) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode(options,function (results, status) {
var city = address_component.long_name;
});
});
}
}
});
我想从控制器那样做
function MainCtrl($scope, geolocation) {
geolocation.getCurrentCity(function(city){
$scope.city = city;
});
};
getCurrentPosition工作正常,城市也确定了,但我不知道如何在控制器中访问城市。
会发生什么?当调用getCurrentCity时,它会调用getCurrentPosition来确定gps coords。这个coords作为参数传递给onSuccess方法吧?所以这与我想在getCurrentCity方法中做的完全相同,但我不知道如何。如果异步地理编码器检索到了城市,我想将新数据应用于onSuccess方法。
有什么想法吗?
答案 0 :(得分:29)
您正在处理回调和异步请求。所以你应该使用$q服务。只需使用$ rootScope和cordovaReady依赖项将其注入您的服务中。 并将承诺添加到您的函数中
getCurrentCity: function () {
var deferred = $q.defer();
this.getCurrentPosition(function (position) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode(options,function (results, status) {
var city = address_component.long_name;
$rootScope.$apply(function(){
deferred.resolve(city);
});
});
});
return deferred.promise;
}
在您的控制器中,执行以下操作来处理承诺。
function MainCtrl($scope, geolocation) {
geolocation.getCurrentCity().then(function(result) { //result === city
$scope.city = result;
//do whatever you want. This will be executed once city value is available
});
};
答案 1 :(得分:5)
试试这个
function MainCtrl($scope, geolocation) {
$scope.city = null;
geolocation.getCurrentCity(function(city){
$scope.city = city;
if(!$scope.$$phase) {
$scope.$digest($scope);
}
});
};
有时候,在实例化控制器时并不总是调用观察者,强制摘要事件,如果范围不同,你可以去你想去的地方,我相信。 如果我不理解你的问题,请告诉我。
哦,我不知道我是否正确阅读了代码,但似乎你没有在你的函数中调用onSuccess回调: 用这个替换你的getCurrentCity函数:
getCurrentCity: function (onSuccess, onError) {
this.getCurrentPosition(function (position) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode(options,function (results, status) {
var city = address_component.long_name;
if(typeof onSuccess === 'function') {
onSuccess(city);
}
});
});
}
答案 2 :(得分:4)
只需在服务中调用onSuccess方法,而不是在那里处理结果。
getCurrentCity: function (onSuccess, onError) {
this.getCurrentPosition(function (position) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode(options, onSuccess);
});
}
在您的控制器中,解析结果并分配城市:
function MainCtrl($scope, geolocation) {
geolocation.getCurrentCity(function(results, status){
// Parse results for the city - not sure what that object looks like
$scope.city = results.city;
});
};
答案 3 :(得分:3)
如果我错了,请纠正我,但所提出的解决方案将不再完全有效,因为较新的Angular版本(> 1.2!?)不再自动解包$ q promises。
因此:
$scope.city = geolocation.getCurrentCity();
永远是一个承诺。所以你总是要使用:
geolocation.getCurrentCity().then(function(city) {
$scope.city = city;
}