如何使用AngularJS asyncValidators处理来自服务器的意外响应?

时间:2014-09-13 15:41:03

标签: angularjs angularjs-directive

我对AngularJS相对较新,并开始尝试使用AngularJS 1.3中提供的新asyncValidators,并且非常喜欢我所看到的。但是,我有一个问题,关于如何处理来自服务器的非快乐路径错误。

使用asyncValidators时,返回一个有意义的promise。假设我们有一个验证器,询问服务器productId是否有效。调用REST api,如果响应返回200,则productId有效。如果响应返回404,则productId无效。

处理响应(例如500或服务器超时)的最佳方法是什么?如果我返回promise.resolve,那么它告诉表单productId是有效的(我们不知道)。如果我返回promise.reject,它会告诉表单productId无效(我们不知道)。我以为我变得可爱并且返回一个空洞的承诺(return $q.defer().promise;),但是这样的形式就像$pending一样等待一个永远不会发生的承诺解决方案。

我在下面提供了一个快速代码示例来演示。如果我采取完全倒退的方法,我很高兴任何建议。

app.directive('isValidProductId', ['$http', '$q', 'productService', function ($http, $q, productService) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, elem, attrs, ctrl) {

            ctrl.$asyncValidators.valid = function (modelValue, viewValue) {
                var value = modelValue || viewValue;
                var deferred = $q.defer();

                var result = productService.getProduct(value).then(function (data) {
                    deferred.resolve(data);
                },
                function (error) {
                    if (error.status == 404) {
                        // The productId is invalid
                        deferred.reject(error);
                    } else {
                        // *** What to do if the response is 500, for example?? ***
                    }
                });

                return deferred.promise;
            }
        }
    }
}])

1 个答案:

答案 0 :(得分:0)

如果您收到500错误,则可以将响应视为当前验证密钥的有效,但将另一个验证密钥设置为无效。因此,通过使用$ http保持这个答案非常通用,下面的内容应该有效。

ngModelController.$asyncValidators.valid = function(modelValue, viewValue) {
  // Make sure to reset the error state from any previous error
  ngModelController.$setValidity('connectionError', true);

  return $http(...).catch(function(error) {
    if (error.status == 500) {
      ngModelController.$setValidity('connectionError', false);
    } else {
      return $q.reject();
    }
  });
});

然后,您可以使用模板或控制器中的密钥connectionError来显示相应的消息。