如何调用angular ngresources $ cancelRequest而不调用错误回调?

时间:2016-12-28 03:53:40

标签: angularjs

在我的Angular应用程序中,用户可以返回上一个屏幕(它只是隐藏当前屏幕)。用户可以在长时间运行的AJAX请求中执行此操作。如果发生这种情况,我想在幕后取消Ajax请求。

我可以让ngresource的$ cancelRequest工作,但它会导致错误回调被抛出。有没有办法让这种情况发生,或者将$ cancelRequest与服务器的通信失败区分开来?提前谢谢。

Plunk(还有一些额外的用户界面):http://plnkr.co/edit/tYj4FRQ9EaCTH4iW9PcL?p=preview

var app = angular.module("app", ["ngResource"]);

app.service("Photos", function($resource) {
  return $resource(null, {}, {
    getPhotos: {
      url: "http://jsonplaceholder.typicode.com/photos",
      method: "GET",
      isArray: true,
      cancellable: true
    }
  });
});

MyController.$inject = ["$log", "$timeout", "Photos"];

function MyController($log, $timeout, Photos) {
  var vm = this;
  vm.message = "Test message";
  vm.result = null;
  vm.photosRequest = null;

  vm.$onInit = function() {
    vm.message = "Test message";
    vm.photosRequest = Photos.getPhotos({},
      function(response) {
        vm.callbackHit = "Good Callback Hit";
        vm.result = response;
      },
      function(response) {
        vm.callbackHit = "Bad Callback Hit (Don't want to see this if $cancelRequest was called, but do if there was an error talking to the server.)"
        vm.result = response;
      }
    );
  };

  // Simulating a cancel request.  How can I tell the error was a cancel and handle differently in the error callback?
  $timeout(function() {
    $log.info("cancelling request");
    vm.photosRequest.$cancelRequest();
  }, 25);
}

app.component("myComponent", {
  templateUrl: "myComponent.html",
  require: {},
  bindings: {},
  controller: MyController,
  controllerAs: "vm"
});

1 个答案:

答案 0 :(得分:1)

您可以执行以下操作:http://plnkr.co/edit/NR9oyXQ8FMdouVAC1Hqx?p=preview

创建了一个额外的属性来跟踪您的请求:

var vm = this;
vm.message = "Test message";
vm.result = null;
vm.photosRequest = null;
// keep track of request state to avoid race conditions
vm.currentRequest = {id: 0, cancelled: false};

取消请求后,您将更新状态。

$timeout(function() {
  $log.info("cancelling request");
  vm.photosRequest.$cancelRequest();
  vm.currentRequest.cancelled = true;
}, 25);

在你的回调中,你在决定做什么时检查状态:

vm.photosRequest = Photos.getPhotos({},
  response => {
    if (vm.currentRequest.id == requestNumber) { // ignore old requests resolving late
      vm.callbackHit = "Good Callback Hit";
      vm.result = response;
    }
  }, error => {
    if (vm.currentRequest.id == requestNumber) { // ignore old requests resolving late
      if (vm.currentRequest.cancelled) { // fail silently
        $log.info('doing nothing in response to cancelled request');
      } else {
        vm.callbackHit = "Bad Callback Hit (Don't want to see this if $cancelRequest was called, but do if there was an error talking to the server.)"
        vm.result = error;
      }
    }
  });

每次发出新请求时,都会重置状态。

var requestNumber = ++vm.currentRequest.id;
vm.currentRequest.cancelled = false; // reset cancelled state on new request
vm.photosRequest = Photos.getPhotos({},...)

这不是最优雅的解决方案,但是如果调用$ cancelRequest,请求状态似乎没有跟踪,所以你必须自己跟踪。