我已经为我的表单创建了验证指令。 它基本上根据来自另一个字段的数据验证字段值。
完美无缺: - )
我的问题是,如果在执行验证后其他字段发生更改,则验证将不会再次运行。
var myApp = angular.module('myApp', [])
.directive('validateInteger', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
var int1val = scope.int1;
scope.int2valid = (viewValue > int1val) ? "valid" : undefined;
if (scope.int2valid == "valid") {
ctrl.$setValidity('higher', true);
return viewValue;
} else {
ctrl.$setValidity('higher', false);
return undefined;
}
});
}
};
});
jsfiddle:http://jsfiddle.net/hanspc/vCFFQ/
答案 0 :(得分:3)
明确引用指令中的某些字段是一个非常糟糕的主意。正如您所看到的,这有很多缺点:不可移植性,代码重复,脆弱性......
做这样的事情:
<input type="text" ng-model="int2" validate-greater-integer="int1" />
并且:
myApp.directive('validateGreaterInteger', function() {
return {
require: 'ngModel',
scope: {
otherInteger : '=validateGreaterInteger',
}
link: function(scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
if (viewValue > scope.otherInteger) {
ctrl.$setValidity('higher', true);
return viewValue;
} else {
ctrl.$setValidity('higher', false);
return undefined;
}
}
});
然后你可以简单地做the typical state control(参见“绑定到表单和控制状态”一节的例子)。
请注意,在这种情况下,您还可以更简单地使用input[number]及其min
参数。
在评论讨论后进行编辑:
嗯,NgModelController.$parsers
中的函数显然只有在模型内容发生变化时才会被调用。您要做的是在int1
或int2
更改时进行验证。所以就这样做:-):
link: function(scope, elm, attrs, ctrl) {
scope.$watch('data', function (data) {
if (data.int2 > data.int1) {
ctrl.$setValidity('higher', true);
return data.int2;
} else {
ctrl.$setValidity('higher', false);
return undefined;
}
}, true);
使用你自己的验证变量(你的小提琴中的int2valid
)也很奇怪。请使用form.int2.$error.higher
,{{1}}。
答案 1 :(得分:2)
也许更简单的解决方案是使用观察者甚至是错误范围内的ng-show方向内的表达式。
在ng-show指令中使用表达式将是这样的:
<span ng-show="int1 > int2" style="color: red; display:none">
否则,您可以观察模型int1和int2中的更改并比较它们的值:
$scope.$watch('int1+int2', function () {
if($scope.int1 > $scope.int2) {
$scope.error = true;
}else {
$scope.error = false;
}
})
<span ng-show="error" style="color: red; display:none">
这是fiddle