我有一个表单,其中一些输入通过指令连接到自定义验证器。输入应该在blur上验证,并通过异步REST API调用来验证。
HTML:
<input type="text"
validate-this
ng-model="thisField"
ng-model-options="{'updateOn': 'blur'}"
ng-pattern="some pattern"
/>
指令(简称简称):
return {
access: 'A',
require: 'ngModel',
scope: false,
link: function (scope, elem, attrs, ngModel) {
ngModel.$asyncValidators.validateThis = function (modelVal, viewVal) {
if (!modelVal && !viewVal) return $q.defer().promise;
// returns a promise from the api service
return api.doSomeValidation();
};
}
};
上面的代码工作正常,但请注意验证函数签名正下方的hackish行:
if (!modelVal && !viewVal) return $q.defer().promise;
如果没有该行,Angular会尝试在应用程序加载时立即验证字段,而不是仅在模糊时验证。这是一个问题,因为实际的验证代码会进行一些字符串解析,并且因为modelVal
和viewVal
都是undefined
,所以JavaScript会抛出错误。
我尝试禁用在加载应用程序时将数据加载到字段中的功能,但错误仍然存在。 ng-pattern
中指定的模式,确实尊重我的意愿,只对字段模糊进行验证 - 它不会尝试在页面加载时进行验证。有没有办法告诉Angular 仅验证模糊,或者让它在页面加载后立即停止尝试验证?或者我错误地使用$asyncValidators
?
答案 0 :(得分:2)
Angular在每个attr。$ observe的信号期间执行$ validate以获取输入验证指令,例如ngPattern。你可以在他们的patternDirective函数中看到它。
我一直试图找到解决方法,因为我使用了许多输入验证(模式,最大长度,要求等),并且我的$ asyncValidators在加载期间触发了7次。这导致Web服务器为每个触发器执行。
解决方案:
将ngPattern测试烘焙到您的异步处理程序中。我可能会选择这个。
ngModel.$asyncValidators.validateThis = function (modelVal, viewVal) {
var deferred = $q.defer();
if (!modelVal && !viewVal)
deferred.resolve();
else if (!myPattern.test(modelVal))
deferred.reject();
else
api.doSomeValidation(value).then(function (result) {
deferred.resolve();
}, function (result) {
deferred.reject();
})
return deferred.promise;
};
希望这有助于我在同一条船上寻找解决方案。