创建一个自定义验证指令,当输入除数字或空格以外的任何内容时,该指令使输入无效。当我以编程方式将值更改为应通过验证的值时,验证状态不会更改。
检查此JSFIDDLE并亲自查看。有什么想法吗?
<div ng-app="test" ng-controller="Ctrl">
<form name="form">
<input custom-validation type="text" ng-model="box.text" name="text" />
</form>
<button ng-click="change()">Change to numbers only</button>
Why doesn't changing to numbers only pass the validation?
</div>
angular.module('test', []);
angular.module('test').directive('customValidation', function () {
'use strict';
return {
require: '?ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$parsers.push(function removeIllegalCharacters(viewValue) {
if(viewValue === undefined){
ngModelCtrl.$setValidity('numbersAndSpacesOnly', true); //empty value is always valid
} else {
var clean = viewValue.replace(/[^0-9 ]+/g, '');
if (viewValue === clean) {
ngModelCtrl.$setValidity('numbersAndSpacesOnly', true);
} else {
ngModelCtrl.$setValidity('numbersAndSpacesOnly', false);
}
}
return viewValue;
});
}
};
});
angular.module('test').controller('Ctrl', function ($scope, $timeout) {
$scope.change = function () {
$scope.box.text = '12345';
}
});
答案 0 :(得分:3)
ngModel
使用2个代码管道(数组)进行验证:
$parsers
数组具有在从用户更改时应用于视图值的功能;每个函数都使用前一个返回的值调用,第一个函数用视图值调用,最后一个函数的返回值写在模型中。这通常用于验证和转换用户输入(例如,从input type="text"
的文本到数字)。
$formatters
数组的工作方式类似,但方向相反。它接收模型值并对其进行转换,最后一个函数的返回值为新视图值。
两个管道中的功能可以选择调用ngModel.$setValidity()
来改变ngModel
的有效性状态。
对于此问题的范围:为了验证模型值,您必须使用$formatters
,类似于您已使用的$parsers
:
angular.module('test').directive('customValidation', function () {
'use strict';
return {
require: '?ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
function removeIllegalCharacters(value) {
if(value === undefined){
ngModelCtrl.$setValidity('numbersAndSpacesOnly', true); //empty value is always valid
} else {
var clean = value.replace(/[^0-9 ]+/g, '');
if (value === clean) {
ngModelCtrl.$setValidity('numbersAndSpacesOnly', true);
} else {
ngModelCtrl.$setValidity('numbersAndSpacesOnly', false);
}
}
return value;
}
ngModelCtrl.$parsers.push(removeIllegalCharacters);
ngModelCtrl.$formatters.push(removeIllegalCharacters);
}
};
});