重试模态弹出窗口AngularJS

时间:2014-05-05 03:35:12

标签: javascript angularjs single-page-application angular-ui-bootstrap

我可以理解如何使用this question

中的重试逻辑来生成$ http请求拦截器

但我无法弄清楚如何使用重试按钮制作模态弹出窗口(angular-ui - bootstrap),每次出现错误时都会加速,甚至反复出现。有人可以给我一些建议吗?

2 个答案:

答案 0 :(得分:4)

这有很多组件,您需要了解链接承诺,以了解它们如何组合在一起。首先是拦截器

app.factory('RetryInterceptor', function($injector, $timeout, $q) {
  return {
   'responseError': function(rejection) {
      // Avoid circular dependency issues
      var Retry = $injector.get('Retry');
      var $http = $injector.get('$http');

      // Timeout is just to keep UI from changing too quickly
      return $timeout(angular.noop,1000).then(function() {
        return Retry.show();
      }).then(function() {
        return $http(rejection.config);
      }, function() {
        return $q.reject(rejection);
      });
    }
  }
});

注册为

app.config(function($httpProvider) {
  $httpProvider.interceptors.push('RetryInterceptor');
});

上面的responseError拦截器返回一个使用返回的Retry.open承诺解析/拒绝的promise。如果该承诺得到解决,那么它将重试原始的$http请求。如果它被拒绝,那么除了从$http的原始调用返回的承诺将被拒绝之外什么也不会发生,并且在没有显示对话框的情况下它将具有相同的拒绝对象。

Retry是一种自定义服务,它公开单个方法open。你可以在拦截器中使用它,但这可以使事情保持模块化:

app.service('Retry', function Retry($window, $modal) {
  this.show  = function() {
    return $modal.open({
      templateUrl: 'retry-dialog.html',
      controller: 'RetryController'
    }).result;
  }
});

show方法返回$modal服务的承诺。此承诺由传递给控制器​​的$modalInstance对象控制:

app.controller('RetryController', function($scope, $modalInstance) {
  $scope.retry = function() {
    // Will resolve the promise
    $modalInstance.close();
  };
  $scope.cancel = function() {
    // Will reject the promise
    $modalInstance.dismiss();
  }
});

模态的模板可以是:

<div class="modal-header">
  <h3>Error!</h3>
</div>
<div class="modal-body">
  <p>Something went wrong!</p>
</div>
<div class="modal-footer">
  <button class="btn btn-primary" ng-click="retry()">Retry</button>
  <button class="btn btn-danger" ng-click="cancel()">Cancel</button>
</div>
然后

将解决承诺,如果&#34;重试&#34;单击,或拒绝承诺,如果&#34;取消&#34;点击。

你可以see all this working in this Plunker

加分:

  • 您可以使用resolve选项将原始失败的详细信息传递给$modal.open,以便您自定义显示的消息。

  • 您可能不希望显示所有请求的对话框。例如,如果为模态获取模板时出错,则最终会出现无限循环。您可以测试http状态代码仅显示某些失败的对话框,或者另一种控制方法是向您传递给config的{​​{1}}对象添加自定义选项,然后您可以测试在$http拦截器中,确定如何处理失败。

答案 1 :(得分:0)

查看此Angular模块http://ngmodules.org/modules/http-auth-interceptor它用于拦截未授权的请求并重试它们。您可以根据需要轻松调整此模块。用您的逻辑替换if (rejection.status === 401 && !rejection.config.ignoreAuthModule)。在'event:auth-loginConfirmed'$rootScope.$on('event:auth-loginConfirmed', ...)绑定app.run()事件以打开您的模态。在您的模态注入authService工厂并调用authService.loginConfirmed()时,这将使用您的错误逻辑重试请求