Рассмотрим форму недействительной, в то время как асинхронный валидатор promises ожидает рассмотрения
У меня есть асинхронный валидатор:
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', ['$http', function($http) {
function link($scope, $element, $attrs, 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.$valid
сам по себе.
Кто-нибудь знает чистое решение?
Ответы
Ответ 1
Вы можете использовать $pending
для проверки того, ожидает ли какой-либо асинхронный валидатор для всей формы или конкретного элемента ввода. Я также добавил тест на $pristine
, чтобы скрыть сообщения об ошибках, когда страница загружается и используется ng-disabled
вместо disabled
на button
.
<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>