我发现这个指令用于过滤货币字段,因此用户只需要输入并隐含小数。
效果很好,除非用户能够在两次按两次字母时输入一封信。我根本不希望他们能够写一封信。
我尝试更改type="number"
,但之后它只允许5位数,然后莫名其妙地消失。你可以在这个plunker看到这个:
http://plnkr.co/edit/Y1olj7Cdz7XKqRmE7BFb?p=preview
所以我需要在这一行中改变一些东西(正则表达式?):
var plainNumber = viewValue.replace(/[^\d|\-+]/g, '');
或以某种方式修复type =“number”以保持输入超过五位数。有人知道该怎么做吗?
答案 0 :(得分:1)
我不熟悉AngularJS,但我可以告诉你的正则表达不完全符合你的意图。
你有这个:[^\d|\-+]
这是一个否定的char类。所有非数字,非+
,非-
和非|
都匹配。另请注意,\d
包含的内容超过[0-9]
,因为它可能会匹配波斯数字等。
我会使用:[^-+0-9]
。通过将-
直接放在^
之后,它不需要转义。
您的解决方案的问题是您在删除字符之前等待输入字符。击键可能比你的场清除它们的速度快。
尽管在Angular或jQuery中没有任何经验,
允许自由输入0-9。输入+
或-
后,它永远不会添加到最后。相反,它出现在开头,覆盖任何现有的标志。也许你应该只运行代码片段并看看自己:
var app = angular.module('App', []);
app.controller('MainCtrl', function($scope) {});
app.directive('inputRestrictor', [function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attr, ngModelCtrl) {
var pattern = /[^+0-9-]/g;
function fromUser(text) {
if (!text)
return text;
var rep = /[+]/g;
var rem = /[-]/g;
rep.exec(text);
rem.exec(text);
var indexp = rep.lastIndex;
var indexm = rem.lastIndex;
text = text.replace(/[+-]/g, '');
if (indexp > 0 || indexm > 0) {
if (indexp > indexm) text = "+" + text;
else text = "-" + text;
}
var transformedInput = text.replace(pattern, '');
ngModelCtrl.$setViewValue(transformedInput);
ngModelCtrl.$render();
return transformedInput;
}
ngModelCtrl.$parsers.push(fromUser);
}
};
}]);

<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js@1.3.0-rc.2" data-semver="1.3.0-rc.2" src=" https://code.angularjs.org/1.3.0-rc.2/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="App">
<div ng-controller="MainCtrl">
<input type="text" ng-model="inputValue" input-restrictor>
<input type="submit" ng-click="getdata()" />
</div>
</body>
</html>
&#13;
答案 1 :(得分:1)
我从你的问题中得到的是:
将输入值与ng-model
绑定时,实际上幕后有两个主要值:$viewValue
和$modelValue
。他们之间的简单关系是这样的:
input DOM value -> $viewValue -> $modelValue
$parsers
仅在$viewValue
和$modelValue
之间有效。因此问题是当您在parser
中插入新的$parsers
时,修改后的值只会影响$modleValue
,因为您只需在解析函数中返回一个新值。
$parsers
是:
每当控件从DOM读取值时,作为管道执行的函数数组。函数按数组顺序调用,每个函数都将返回值传递给下一个。最后一个返回值将转发到$ validators集合
更多信息:https://docs.angularjs.org/api/ng/type/ngModel.NgModelController# $解析器
解析器函数中返回的值不会影响$viewValue
,因此您需要做的是更改该值并反映输入DOM元素。
代码示例:
app.directive('format', ['$filter', function ($filter) {
return {
require: 'ngModel',
link: function (scope, elem, attrs, ctrl) {
if (!ctrl) return;
ctrl.$parsers.unshift(function (viewValue) {
var plainNumber = viewValue.replace(/[^\d|\-+]/g, '');
//use angular internal 'number' filter
plainNumber = $filter('number')(plainNumber/100,2);
//update the $viewValue
ctrl.$setViewValue(plainNumber);
//reflect on the DOM element
ctrl.$render();
//return the modified value to next parser
return plainNumber;
});
}
};
}]);
工作的plnkr在这里:http://plnkr.co/edit/aoBWhJhlJLiEhBm5hRNX?p=preview
最后,当你输入第6位并消失的原因是:
当您输入6位数时,浏览器会将您输入的数字转换并格式化为这种格式:'1,234.56'(注意COMMA',',分隔符可能会推迟到不同的浏览器上),您将看到控制台中有角度的警告:
指定值“1,234.56”不是有效数字。该值必须与以下正则表达式匹配: - ?(\ d + | \ d +。\ d + + |。\ d +)([eE] [ - +]?\ d +)?
由输入元素type='number'
的限制引起,angular将执行额外的内部验证,以匹配由角度本身定义的规则。