簡體   English   中英

發生錯誤時如何使“正在加載”消息消失?

[英]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塊起作用,則需要resolvereject 由於$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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM