我遇到指令问题。该指令的目的是轻松添加验证,而无需手动将ng-class(以及其他内容)添加到元素中,以便显示错误状态。我只是想在我的元素上放置一个“validation”指令,并在出现错误状态时生成相应的类(和错误消息)。
就验证而言,它运作良好,但它会产生奇怪的副作用。每当我在输入框中编辑一个具有验证指令的值时,它就会将插入符号移动到输入字段中文本的末尾。似乎是我正在编译元素(在这种情况下是包含该元素的父元素)。
Here is a jsbin显示问题。要重现,请在字段中键入值,然后将插入符号放在刚刚键入的值的中间,然后尝试键入另一个字符。请注意,它会将您移动到字段的末尾。请注意,如果删除该值,则字段标签将按预期变为红色以显示验证错误(该字段是必需的)。
这是指令(来自jsbin):
angular.module('app', [])
.directive('validation', function($compile) {
return {
require: 'ngModel',
restrict: 'A',
compile: function(compileElement, attrs) {
var formName = compileElement[0].form.name;
compileElement.removeAttr('validation');
compileElement.parent().attr('ng-class', formName + "['" + attrs.name + "'].$invalid && " + formName + "['" + attrs.name + "'].$dirty ? 'error' : ''");
return function(scope, element) {
$compile(element.parent())(scope);
}
}
};
});
这是html:
<html>
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular.min.js"></script>
</head>
<body ng-app="app">
<form name="subscribeForm">
<label>
First Name
<input type="text"
id="firstName"
name="firstName"
ng-model="userInfo.FirstName"
required
validation/>
</label>
</form>
</body>
</html>
答案 0 :(得分:1)
不确定你是否已经解决了这个问题,但我遇到了类似的问题。在Preserving cursor position with angularjs找到了解决方案。为方便起见,下面是解决此问题的指令代码段。
app.directive('cleanInput', function() {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModelController) {
var el = element[0];
function clean(x) {
return x && x.toUpperCase().replace(/[^A-Z\d]/g, '');
}
ngModelController.$parsers.push(function(val) {
var cleaned = clean(val);
// Avoid infinite loop of $setViewValue <-> $parsers
if (cleaned === val) return val;
var start = el.selectionStart;
var end = el.selectionEnd + cleaned.length - val.length;
// element.val(cleaned) does not behave with
// repeated invalid elements
ngModelController.$setViewValue(cleaned);
ngModelController.$render();
el.setSelectionRange(start, end);
return cleaned;
});
}
}
});
该指令有不同的用途,但请根据您的要求进行修改。
答案 1 :(得分:0)
如果您没有使用内置验证模型/流程,那么您做错了。查看angular-js网站上的教程:
http://code.angularjs.org/1.2.13/docs/guide/forms
此外,您不应该在编译阶段进行元素操作。
您需要查看名为自定义验证的部分。
使用ctrl.$parsers
方法。您将解析器添加到解析器列表中,并且您的fn将在模型更改时运行。然后使用ctrl.$setValidity('strNameOfValidation', true)
设置有效性。然后,Angular将为您添加一个类 - 名为.ng-valid-float
或.ng-invalid-float
。
var FLOAT_REGEXP = /^\-?\d+((\.|\,)\d+)?$/;
app.directive('smartFloat', function() {
return {
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
if (FLOAT_REGEXP.test(viewValue)) {
ctrl.$setValidity('float', true);
return parseFloat(viewValue.replace(',', '.'));
} else {
ctrl.$setValidity('float', false);
return undefined;
}
});
}
};
});