[英]How to make 'Loading' message disappear when an error occurs?
當用戶單擊“搜索”按鈕時,將出現“正在加載”消息,當結果出現在屏幕上時該消息將消失。
如果地理位置失敗,則會向他們顯示警報,但“正在加載”消息將保留在屏幕上。 顯然,我希望地理定位失敗時加載消息消失。
我知道我必須對代碼做一些事情,但是我真的不知道從哪里開始。 我以為只是在控制器中添加.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
我相信這里的主要問題是您基本上不在GeoLocation工廠中使用deferred.reject,而應該使用navigator.geolocation:
} else {
//alert('Your browser does not support Geo Location.');
deferred.reject(response);
}
之后,您可以輕松地在控制器中添加一個簡單的.catch語句。 此catch語句將提交警報,然后您還可以將loading設置為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;
});
希望這有助於回答您的問題。
您沒有兌現承諾。 您需要拒絕承諾,因為它失敗了。 像這樣
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
塊起作用,則需要resolve
或reject
。 由於$q.deferred
是反模式 ,請使用$ q構造函數 - $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;
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.