2014-09-13 42 views
0

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

使用asyncValidators时,您返回一个承诺,这是有道理的。假设我们有一个验证器,询问服务器是否有一个productId。调用REST api,如果响应返回为200,则productId有效。如果响应返回为404,则productId无效。

处理响应(如500或服务器超时)的最佳方法是什么?如果我返回promise.resolve,那么它会告诉formId是有效的(我们不知道)。如果我返回promise.reject,它会告诉formId无效(我们不知道)。我想我会变得可爱并且回复一个空的承诺(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; 
      } 
     } 
    } 
}]) 

回答

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来显示相应的消息。

+0

感谢米哈尔 - 这些似乎是一种合理的模式。 – 2014-09-16 01:23:08