当用户点击'搜索'按钮,'正在加载'消息显示,并且当结果显示在屏幕上时消失。
如果地理位置失败,则会向他们显示提醒,但是“加载”#39;消息留在屏幕上。显然,我希望加载消息在地理定位失败时消失。
我知道我必须用代码做一些事情,但我真的不知道从哪里开始。我认为这只是在控制器中添加.finally
函数的情况,但这并不起作用。
地理定位工厂:
beerStalker.factory('GeoLocation', function() {
return {
getLocation: function() {
var deferred = $.Deferred();
// if geo location is supported
if(navigator.geolocation) {
// get current position and pass the results to getPostalCode or time out after 5 seconds if it fails
navigator.geolocation.getCurrentPosition(deferred.resolve, this.geoLocationError, {
timeout: 5000
});
} else {
alert('Your browser does not support Geo Location.');
}
return deferred.promise();
},
geoLocationError: function() {
alert('Geo Location failed.');
}
}
});
控制器:
beerStalker.controller('BeerStalkController', ['$scope', '$resource', 'ApiCall', 'GeoLocation', function($scope, $resource, ApiCall, GeoLocation) {
$scope.autoSearch = function() {
$scope.loading = true;
$.when(GeoLocation.getLocation()).then(function(data, textStatus, jqXHR) {
return [data.coords.longitude, data.coords.latitude];
}).then(function(location) {
ApiCall.autoSearch(location[1], location[0]).then(function(results){
$scope.searchResult = results
$scope.loading = false;
});
});
};
$scope.customSearch = function() {
$scope.loading = true;
ApiCall.customSearch($scope.cityName).then(function(results){
$scope.searchResult = results
$scope.loading = false;
});
};
}]);
PS它是用Angular构建的。 Github回购:https://github.com/Yorkshireman/beerstalker
答案 0 :(得分:0)
我认为这里的主要问题是你不应该在你的GeoLocation工厂中使用deferred.reject,当你应该使用navigator.geolocation时:
} else {
//alert('Your browser does not support Geo Location.');
deferred.reject(response);
}
在此之后,您可以在控制器中轻松添加简单的.catch语句。此catch语句将提交警报,然后您还可以将加载设置为false,如下所示:
.then(function(location) {
ApiCall.autoSearch(location[1], location[0]).then(function(results){
$scope.searchResult = results
$scope.loading = false;
})
.catch(function(location){
alert('Your browser does not support Geo Location.');
$scope.loading = false;
});
希望这有助于回答您的问题。
答案 1 :(得分:0)
你的承诺未解决。你需要拒绝承诺,因为它失败了。像这样。
beerStalker.factory('GeoLocation', function() {
return {
getLocation: function() {
var deferred = $.Deferred();
// if geo location is supported
if(navigator.geolocation) {
// get current position and pass the results to getPostalCode or time out after 5 seconds if it fails
navigator.geolocation.getCurrentPosition(deferred.resolve, this.geoLocationError, {
timeout: 5000
});
} else {
deffered.reject('Your browser does not support Geo Location.');
}
return deferred.promise();
},
geoLocationError: function() {
alert('Geo Location failed.');
}
}
});
在承诺中,需要在then()中提供第二次失败回调。 then(function(success){}, function(failure){})
beerStalker.controller('BeerStalkController', ['$scope', '$resource', 'ApiCall', 'GeoLocation', function($scope, $resource, ApiCall, GeoLocation) {
$scope.autoSearch = function() {
$scope.loading = true;
$.when(GeoLocation.getLocation()).then(function(data, textStatus, jqXHR) {
return [data.coords.longitude, data.coords.latitude];
}, function(failureReason){alert(failureReason);}).then(function(location) {
ApiCall.autoSearch(location[1], location[0]).then(function(results){
$scope.searchResult = results
$scope.loading = false;
});
}).finally(function(){$scope.loading = false});
};
$scope.customSearch = function() {
$scope.loading = true;
ApiCall.customSearch($scope.cityName).then(function(results){
$scope.searchResult = results
$scope.loading = false;
});
};
}]);
请注意,我已将警报移至故障中。我将$scope.loading=false;
移动到finally语句,以确保每次都执行它。
答案 2 :(得分:0)
如果您希望resolve
数据块生效,则需要reject
或finally
。如$q.deferred
is an anti-pattern,请改用$q constructor - $q(resolve, reject)
。
beerStalker.factory('GeoLocation', function () {
return {
getLocation : function () {
return $(resolve, reject) {
// if geo location is supported
if (navigator.geolocation) {
// get current position and pass the results to getPostalCode or time out after 5 seconds if it fails
navigator.geolocation.getCurrentPosition(resolve, reject, { // if it fails 'reject' will be called
timeout : 5000
});
} else {
alert('Your browser does not support Geo Location.');
reject();
}
}
},
/** notify about the error in the controller
geoLocationError : function () {
alert('Geo Location failed.');
}
**/
}
});
/** the GeoLocation.getLocation call in the controller **/
GeoLocation.getLocation().then(function (data, textStatus, jqXHR) { // you don't need when because it's an angular $q promise
return [data.coords.longitude, data.coords.latitude];
}).then(function (location) {
return ApiCall.autoSearch(location[1], location[0]);
}).then(function (results) {
$scope.searchResult = results;
}).catch(function (error) { // catch error and show alert
alert('Geo Location failed.');
}).finally (function () { // remove loader
$scope.loading = false;
});