现在,在我的验证指令中,我“手动”设置验证状态,如下所示:
$element.on('focus', function() {
$scope.$apply(function() {
ngModelCtrl.$setValidity('length', true);
});
});
$element.on('blur', function() {
$scope.$apply(function() {
if (ngModelCtrl.$modelValue && ngModelCtrl.$modelValue.length === +$attrs.maxlength) {
ngModelCtrl.$setValidity('length', true);
}
else if (ngModelCtrl.$modelValue.length < +$attrs.maxlength && ngModelCtrl.$modelValue.length > 0) {
ngModelCtrl.$setValidity('length', false);
}
}
});
但我想使用 $validators
设置验证状态,并保存验证行为(在模糊/焦点事件上)。
我无法将 ng-model-options
与 updateOn: 'blur'
一起使用。
还有其他选择可以做到这一点吗?
最佳答案
因此,要使用自定义验证器,您需要稍微不同地构造指令。主要区别是您需要 require ngModel
。
指令
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
// Run validator for maxLenth
ngModel.$validators.customMaxLength = function(value) {
var status = false;
if(value.length <= attrs.maxLengthValidator) {
console.log(attrs.maxLengthValidator);
status = true;
}
return status;
};
}
}
需要注意的重要事项。如果您使用属性进行验证并且该值可能会更改,您需要监视该值并手动运行验证器函数。因为模型不会更改,所以验证器不会自动触发。
将以下内容添加到指令
scope.$watch(function() {
return attrs.maxLengthValidator;
},function() {
ngModel.$validate();
});
如果验证器返回 false,您的表单将自动将 $valid
设置为 false
HTML
在下面的示例中,我使用 Angular 消息来显示有效输出。这是一个需要包含的可选模块。
<form name="myForm">
<div class="form-group" ng-class="{'has-error':myForm.testField.$invalid}">
<label class="control-label" for="testInput">Test Field</label>
<input class="form-control" type="text" name="testField"
max-length-validator="3" required ng-model="testField"/>
</div>
</form>
<div ng-messages ng-messages-multiple class="bg-danger" for="myForm.testField.$error">
<div ng-message when="required">Please enter value</div>
<div ng-message when="customMaxLength">To Long</div>
</div>
<小时/>
关于您关于在模糊时触发验证器的问题
如果模型值无效,您并不真的想更新 ngModel。
我建议使用样式和焦点属性与字段来根据字段的焦点切换显示。
将类似以下内容添加到您的输入字段
ng-focus="myForm.testField.focus=true" ng-blur="myForm.testField.focus=false"
然后使用 ng-class
、ng-show
或 ng-hide
进行检查来更新您的显示。
这已添加到 plnkr
关于javascript - 在模糊/焦点事件上使用 $validators,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32693716/