AngularJS 由其他字段触发的表单验证
AngularJS form validation triggered by other fields
我有一个 angularjs 应用程序,必须使用自定义业务规则进行表单验证。
问题是我对特定输入字段的验证规则依赖于其他字段,除了实际模型值更改时,我不知道如何触发验证。
案例是一个动态的员工列表,每个员工都有一个要输入的动态时间列表。一个规则是这些时间不能重叠,这意味着一个值可能由于另一个值被更改而无效,反之亦然。
我还必须为每个字段显示一条错误消息。
表单内容是从具有几层嵌套转发器的数据模型生成的。
我制作了一个包含不同验证规则的自定义指令,当该字段发生变化时它会很好地触发。
我正在使用 ngMessages 根据违反的业务规则显示适当的错误消息。
问题是,当一个特定字段发生更改时,我如何触发对所有其他字段的验证?最好我应该只触发值正在更改的员工的所有字段的验证,因为一个员工的值不会影响其他员工的验证。
此处的 fiddle 是我的情况的简化版本,其中 "overlap" 规则仅检查两个数字是否相同。
html:
<form name="demoForm">
<div ng-repeat="employee in list">
<div ng-bind="employee.name"></div>
<div ng-repeat="day in employee.days" ng-form="employeeForm">
<input ng-model="day.hours" name="hours" custom-validate="{day: day, days: employee.days}" ng-model-options="{allowInvalid:true}" />
<span ng-messages="employeeForm.hours.$error">
<span ng-message="number">Should be a number.</span>
<span ng-message="businessHours">The number is outside business hours.</span>
<span ng-message="max">The number is too large.</span>
<span ng-message="overlap">The number must be unique for each employee.</span>
</span>
</div>
<br/>
</div>
</form>
验证指令:
angular.module('app').directive('customValidate', [validator]);
function validator() {
return {
restrict: 'A',
require: 'ngModel',
scope: {
data: '=customValidate'
},
link: linkFunc,
};
function linkFunc(scope, element, attrs, ctrl) {
ctrl.$validators.number = function(value) {
return value === "" || Number.isInteger(+value);
}
ctrl.$validators.businessHours = function(value) {
// imagine other validation data here
return value === "" || (value >= 1 && value <= 10);
}
ctrl.$validators.overlap = function(value) {
if (value === "") {
return true;
}
// find all other entries with identical value excluding self
var identical = scope.data.days.filter(function(x) {
return x !== scope.data.day && +x.hours === +value;
});
return identical.length === 0;
};
}
}
Fiddle 这里:
http://jsfiddle.net/maxrawhawk/dvpjdjbv/
答案:
指令 link 函数末尾的这段代码:
scope.$watch('data', function(){
ctrl.$validate();
}, true);
观察标记中与验证相关的数据,其中最重要的细节 'true' 作为第三个参数,使 $watch 检查对象是否相等。
更新 fiddle:
http://jsfiddle.net/maxrawhawk/dvpjdjbv/12/
我有一个 angularjs 应用程序,必须使用自定义业务规则进行表单验证。 问题是我对特定输入字段的验证规则依赖于其他字段,除了实际模型值更改时,我不知道如何触发验证。
案例是一个动态的员工列表,每个员工都有一个要输入的动态时间列表。一个规则是这些时间不能重叠,这意味着一个值可能由于另一个值被更改而无效,反之亦然。 我还必须为每个字段显示一条错误消息。
表单内容是从具有几层嵌套转发器的数据模型生成的。 我制作了一个包含不同验证规则的自定义指令,当该字段发生变化时它会很好地触发。 我正在使用 ngMessages 根据违反的业务规则显示适当的错误消息。
问题是,当一个特定字段发生更改时,我如何触发对所有其他字段的验证?最好我应该只触发值正在更改的员工的所有字段的验证,因为一个员工的值不会影响其他员工的验证。
此处的 fiddle 是我的情况的简化版本,其中 "overlap" 规则仅检查两个数字是否相同。
html:
<form name="demoForm">
<div ng-repeat="employee in list">
<div ng-bind="employee.name"></div>
<div ng-repeat="day in employee.days" ng-form="employeeForm">
<input ng-model="day.hours" name="hours" custom-validate="{day: day, days: employee.days}" ng-model-options="{allowInvalid:true}" />
<span ng-messages="employeeForm.hours.$error">
<span ng-message="number">Should be a number.</span>
<span ng-message="businessHours">The number is outside business hours.</span>
<span ng-message="max">The number is too large.</span>
<span ng-message="overlap">The number must be unique for each employee.</span>
</span>
</div>
<br/>
</div>
</form>
验证指令:
angular.module('app').directive('customValidate', [validator]);
function validator() {
return {
restrict: 'A',
require: 'ngModel',
scope: {
data: '=customValidate'
},
link: linkFunc,
};
function linkFunc(scope, element, attrs, ctrl) {
ctrl.$validators.number = function(value) {
return value === "" || Number.isInteger(+value);
}
ctrl.$validators.businessHours = function(value) {
// imagine other validation data here
return value === "" || (value >= 1 && value <= 10);
}
ctrl.$validators.overlap = function(value) {
if (value === "") {
return true;
}
// find all other entries with identical value excluding self
var identical = scope.data.days.filter(function(x) {
return x !== scope.data.day && +x.hours === +value;
});
return identical.length === 0;
};
}
}
Fiddle 这里: http://jsfiddle.net/maxrawhawk/dvpjdjbv/
答案: 指令 link 函数末尾的这段代码:
scope.$watch('data', function(){
ctrl.$validate();
}, true);
观察标记中与验证相关的数据,其中最重要的细节 'true' 作为第三个参数,使 $watch 检查对象是否相等。 更新 fiddle: http://jsfiddle.net/maxrawhawk/dvpjdjbv/12/