我需要一个输入字段,我只能输入值1,2或3,因此我正在尝试构建一个指令,如果它与这些值不匹配,则会阻止对模型的所有更改。
例如,值为1,我将其更改为5,它应该仍为1.
我整理了一个小小提琴http://jsfiddle.net/kannix/Q5YKE/,但使用$解析器很可能是错误的。
app.directive('myvalidator', function () {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
var validValues = [1,2,3];
ctrl.$parsers.push(function (value) {
if (validValues.indexOf(value) === -1){
//what to do here? should refuse wrong value and leave the old one
}
});
}
}
})
答案 0 :(得分:21)
我最近为此写了一个指令。它需要一个regExp对象来验证传入的按键,并且只有在有效时才允许它们:
// forces keystrokes that satisfy the regExp passed
app.directive("regExpRequire", function() {
var regexp;
return {
restrict: "A",
link: function(scope, elem, attrs) {
regexp = eval(attrs.regExpRequire);
var char;
elem.on("keypress", function(event) {
char = String.fromCharCode(event.which)
if(!regexp.test(elem.val() + char))
event.preventDefault();
})
}
}
})
模板用法:<input type="text" reg-exp-require="/^[a-zA-Z]$/">
或者在你的情况下:<input type="text" reg-exp-require="/^[1-3]*$/">
答案 1 :(得分:6)
我建议使用ng-pattern-restrict
指令。
Get the library并简单地装饰你的输入:
<input type="text" pattern="[0-9]+" ng-pattern-restrict />
GitHub:AlphaGit/ng-pattern-restrict
答案 2 :(得分:4)
您可以随时收听keypress
事件并阻止该角色完成。 Here is a plunker
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.validValues = ['a','1','2'];
});
app.directive('myValidator', function ($parse) {
return {
scope: {
validValues: '=validValues'
},
link: function (scope, elm, attrs) {
elm.bind('keypress', function(e){
var char = String.fromCharCode(e.which||e.charCode||e.keyCode), matches = [];
angular.forEach(scope.validValues, function(value, key){
if(char === value) matches.push(char);
}, matches);
if(matches.length == 0){
e.preventDefault();
return false;
}
});
}
}
});
答案 3 :(得分:2)
我实际上必须建立并修改Ian Haggerty的答案形式。他的代码运作良好,直到我开始以不同的方式测试它。我特意试图测试低于100的值,但我得到了一些奇怪的结果。
如果我的输入中有100,那么尝试插入一个十进制数使其成为10.0,Ian的修复程序没有考虑到这一点,并说它不匹配我的正则表达式(即使我允许最多两位小数)。事实证明它总是附加我在它正在测试的字符串的END处按下的字符,即使我将它插入中间。
我的更改是将原始值存储在“keypress”上,然后存储在“keyup”(或“更改”,如果您愿意),它会检查新值。如果无效,则恢复原状。
不幸的是,它确实会简要更新模型,但至少它允许您在输入值的中间或开头键入字符,并且仍然可以正确匹配正则表达式。在Angular 1.3中,我们可以使用ng-model-options =“{debounce:250}”来解决这个问题。任何依赖于此模型更改的代码都是无能为力的帮助。
usage: <input ... validate-with="/^([\d]{1,2}\.[\d]{1,2}|\.?[\d]{1,2}|100)?$/" />
.directive("validateWith", [function(){
return {
restrict: "A",
link: function($scope, $el, $attrs){
var regexp = eval($attrs.validateWith);
var origVal;
// store the current value as it was before the change was made
$el.on("keypress", function(e){
origVal = $el.val();
});
// after the change is made, validate the new value
// if invalid, just change it back to the original
$el.on("keyup", function(e){
if(!regexp.test($el.val())){
$el.val(origVal);
}
});
}
}
}]);