在 Angular 中正确过滤输入字段 [英] Properly filtering an input field in Angular

查看:19
本文介绍了在 Angular 中正确过滤输入字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现这个指令用于过滤货币字段,因此用户只需要输入并隐含小数.

I found this directive for filtering a field for currency, so a user just needs to type and the decimal is implied.

它工作得很好,除了用户按下一个字母两次就可以输入一个字母.我根本不想让他们写信.

It works well, except that a user is able to put in a letter if they press a letter twice. I don't want them to be able to put in a letter at all.

我尝试更改 type="number" 但随后它只允许 5 位数字,然后莫名其妙地消失.你可以在这个plunker看到这一点:

I tried changing the type="number" but then it would only allow 5 digits before disappearing inexplicably. You can see this at this plunker:

http://plnkr.co/edit/Y1olj7Cdz7XKqRmE7BFb?p=preview

所以要么我需要在这一行中改变一些东西(正则表达式?):

So either I need to change something (the regex?) in this line:

var plainNumber = viewValue.replace(/[^\d|\-+]/g, '');

或以某种方式修复 type="number" 以保持输入超过五位数.有人知道在这里做什么吗?

or somehow fix the type="number" to keep input past five digits. Anybody know what to do here?

推荐答案

我从你的问题中得到的是:

What I got from your issue are :

  1. 只接受数字,其他的都用''代替
  2. 保留两位小数
  3. 过滤用户的输入并根据用户类型反映/修改输入元素的值

当使用ng-model绑定输入值时,实际上幕后内部主要有两个值:$viewValue$modelValue.而他们之间的简单关系是这样的:

When binding the input value with ng-model, actually there are two main values behind the scenes internally: $viewValue and $modelValue. And a simple relationship between them is like this:

输入DOM值->$viewValue ->$modelValue

$parsers 只在 $viewValue$modelValue 之间工作.所以问题是当你在 $parsers 中插入一个新的 parser 时,修改后的值只会影响 $modelValue 因为你只是简单地返回一个解析函数中的新值.

The $parsers only work between $viewValue and $modelValue. So the problem is when you insert a new parser into the $parsers, the modified value will only affect the $modleValue as you simply return a new value in the parse function.

$parsers 是:

每当控件从 DOM 读取值时,作为管道执行的函数数组.这些函数按数组顺序调用,每个函数都将其返回值传递给下一个.最后一个返回值被转发到 $validators 集合

Array of functions to execute, as a pipeline, whenever the control reads value from the DOM. The functions are called in array order, each passing its return value through to the next. The last return value is forwarded to the $validators collection

更多关于:https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#$parsers

more on : https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#$parsers

解析器函数中的返回值不会影响 $viewValue,因此您需要做的是更改该值并反映在输入的 DOM 元素上.

And the returned value in the parser function WON'T affect the $viewValue so what you need to do is to also change that value and reflect on the input DOM element.

代码示例:

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=预览

A working plnkr is here: http://plnkr.co/edit/aoBWhJhlJLiEhBm5hRNX?p=preview

最后,当你输入第6个数字时它消失的原因是:

At last, the reason why when you type 6th digit and it disappear is:

当您输入 6 位数字时,浏览器会将您输入的数字转换并格式化为这种格式:'1,234.56'(注意逗号 ',',分隔符在不同浏览器上可能会有所不同),您将在控制台中看到 angular 给出的警告:

As you type 6 digits, the browser will convert and format the number you type to this kind of format: '1,234.56' (pay attention to the COMMA ',', the separator may defer on different browsers) , and you will see a warning given by angular in the console :

指定的值1,234.56"不是有效数字.该值必须与以下正则表达式匹配:-?(\d+|\d+.\d+|.\d+)([eE][-+]?\d+)?

The specified value "1,234.56" is not a valid number. The value must match to the following regular expression: -?(\d+|\d+.\d+|.\d+)([eE][-+]?\d+)?

这是由 type='number' 对输入元素的限制引起的,angular 将执行额外的内部验证以匹配 angular 本身定义的规则.

which is caused by the restriction from the type='number' on the input element, angular will perform extra internal validation to match the rule defined by angular itself.

这篇关于在 Angular 中正确过滤输入字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆