我有一个异步验证器:
app.directive('validateBar',['$http',function($http) { function link($scope,$element,$attrs,ngModel) { ngModel.$asyncValidators.myValidator = function(value) { return $http.get('/endpoint/' + value); }; } return { require: 'ngModel',link: link }; }]);
表单模板:
<form name="myForm" ng-submit="foo.$valid && saveForm()"> <input name="bar" ng-model="bar" data-validate-bar> <p ng-show="myForm.bar.$error.myValidator">Your bar is wrong</p> <button disabled="myForm.$invalid"> </form>
问题:在myValidator承诺待处理的时候,我希望我的伴随形式无效.
当异步验证器处于待处理状态时,我知道有两种使表单无效的方法,但它们是冗长的和/或恶意的.
// Workaround 1: Mark another validator as invalid while the validator promise is pending. // I cannot mark 'myValidator' as invalid,gets set to valid immediately by Angular. app.directive('validateSomething',ngModel) { ngModel.$setValidity('async',false); ngModel.$asyncValidators.myValidator = function(value) { return $http.get('/endpoint/' + value).then(function() { ngModel.$setValidity('async',true); }); }; } return { require: 'ngModel',link: link }; }]);
<!-- Workaround 2: Prevent submitting through the UI --> <form name="myForm" ng-submit="myForm.$valid && !myForm.$pending && saveForm()"> <input name="bar" ng-model="bar" data-validate-bar> <p ng-show="myForm.bar.$error.myValidator">Your bar is wrong</p> <button disabled="myForm.$invalid || myForm.$pending"> </form>
我不喜欢解决方法1,因为我将另一个验证器(async)标记为无效,这可能会产生意想不到的副作用,我不喜欢解决方法2,因为我不能再信任form.
有谁知道一个干净的解决方案?
您可以使用$pending来测试整个表单或特定输入元素上的某些异步验证器是否挂起.我还在$pristine上添加了一个测试,以在页面加载时隐藏错误消息,并使用ng禁用,而不是在按钮上禁用.
<form name="myForm" ng-submit="foo.$valid && saveForm()"> <input name="bar" ng-model="bar" data-validate-bar> <div ng-show="! myForm.$pristine"> <p ng-show="myForm.bar.$pending.myValidator || myForm.bar.$error.myValidator">Your bar is wrong</p> </div> <button ng-disabled="myForm.$invalid || myForm.$pending">Do smth</button> </form>