Angular:强制自定义表单验证器对任何字段输入 运行
Angular: force custom form validator to run on any field input
我为密码字段编写了一个自定义验证程序,以验证以下场景:
- 如果用户定义了id,则密码始终有效(可以为空,表示不变)
- 如果用户没有定义id,则密码不能为空(新用户必须有密码)
问题是,我注意到验证器仅在用户与该字段交互时才为 运行(不像 required
,显然在任何输入上都是 运行)。这使得表单看起来有效,即使新用户的密码为空。一旦我与密码输入进行交互,一切似乎都很好。
我已经通过记录不完整的 ngRequired
指令解决了业务逻辑需求,但我真的很想了解有关自定义验证器的问题,以防我再次 运行 进入它。
您可以在此处尝试 ui-validate 您的业务:
$scope.passwordValidation = {
length: '$value.length >= 5 || $value.length == 0'
};
$scope.password2Validation = {
same_passwords: 'userPassword.value==$value'
};
然后是你的 HTML:
<input id="password" class="form-control" type="password" ng-model="userPassword.value"
name="password" ui-validate="passwordValidation"/>
<input id="password2" class="form-control" type="password" ng-model="userPassword.confirm"
name="password2" ui-validate="password2Validation" ui-validate-watch="'userPassword.value'"/>
请注意 ui-validate-watch
告诉 ui-validate 关心其他密码字段。
放弃这个之后,我 运行 又陷入了这个问题,但我找不到解决方法。 Fortunatel,我找到了解决方案:
当您制作自定义验证器时,您需要将其绑定到模型字段,而不是表单字段。这使得它始终正确验证(可以假设由于表单字段上的 $modelValue 和 $viewValue 属性之间的差异会混淆事物)。请参阅下面的代码以供参考:
<input type="password" class="form-control" id="confirmpass" name="confirmpass" placeholder="Repeat Password"
ng-model="controller.selectedUser.passwordRepeat"
compare-to="controller.selectedUser.password"/>
和自定义验证器:
angular.module("compareTo", []).directive("compareTo", function() {
return {
require: "ngModel",
scope: {
otherModelValue: "=compareTo"
},
link: function(scope, element, attributes, ngModel) {
ngModel.$validators.compareTo = function(modelValue) {
return modelValue == scope.otherModelValue;
};
scope.$watch("otherModelValue", function() {
ngModel.$validate();
});
}
};
);
我为密码字段编写了一个自定义验证程序,以验证以下场景:
- 如果用户定义了id,则密码始终有效(可以为空,表示不变)
- 如果用户没有定义id,则密码不能为空(新用户必须有密码)
问题是,我注意到验证器仅在用户与该字段交互时才为 运行(不像 required
,显然在任何输入上都是 运行)。这使得表单看起来有效,即使新用户的密码为空。一旦我与密码输入进行交互,一切似乎都很好。
我已经通过记录不完整的 ngRequired
指令解决了业务逻辑需求,但我真的很想了解有关自定义验证器的问题,以防我再次 运行 进入它。
您可以在此处尝试 ui-validate 您的业务:
$scope.passwordValidation = {
length: '$value.length >= 5 || $value.length == 0'
};
$scope.password2Validation = {
same_passwords: 'userPassword.value==$value'
};
然后是你的 HTML:
<input id="password" class="form-control" type="password" ng-model="userPassword.value"
name="password" ui-validate="passwordValidation"/>
<input id="password2" class="form-control" type="password" ng-model="userPassword.confirm"
name="password2" ui-validate="password2Validation" ui-validate-watch="'userPassword.value'"/>
请注意 ui-validate-watch
告诉 ui-validate 关心其他密码字段。
放弃这个之后,我 运行 又陷入了这个问题,但我找不到解决方法。 Fortunatel,我找到了解决方案:
当您制作自定义验证器时,您需要将其绑定到模型字段,而不是表单字段。这使得它始终正确验证(可以假设由于表单字段上的 $modelValue 和 $viewValue 属性之间的差异会混淆事物)。请参阅下面的代码以供参考:
<input type="password" class="form-control" id="confirmpass" name="confirmpass" placeholder="Repeat Password"
ng-model="controller.selectedUser.passwordRepeat"
compare-to="controller.selectedUser.password"/>
和自定义验证器:
angular.module("compareTo", []).directive("compareTo", function() {
return {
require: "ngModel",
scope: {
otherModelValue: "=compareTo"
},
link: function(scope, element, attributes, ngModel) {
ngModel.$validators.compareTo = function(modelValue) {
return modelValue == scope.otherModelValue;
};
scope.$watch("otherModelValue", function() {
ngModel.$validate();
});
}
};
);