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

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

问题描述

我发现这个指令用于过滤的货币领域,使用户只需键入并小数点是隐含的。

它运作良好,但用户能够把在信中,如果他们两次$ $ p PSS的信。我不希望他们能够把信都没有。

我试图改变键入=号,但随后将只允许5位莫名其妙地消失了。您可以在此plunker看到这一点:

http://plnkr.co/edit/Y1olj7Cdz7XKqRmE7BFb?p=$p$ PVIEW

所以,或者我需要改变这一行的东西(的正则表达式):

  VAR plainNumber = viewValue.replace(/ [^ \\ D | \\  -  +] /克,'');

或以某种方式固定类型=数字,以保持输入过去五年的数字。有人知道这里做什么?


解决方案

我从你的问题得到了什么是:


  1. 只接受数字,取代其他一切与''

  2. 保持2小数位数

  3. 过滤用户的输入,并反映/值修改为
  4. input元素为用户类型

当结合使用 NG-模型,居然还有后面的内部幕后两大值的输入值: $ viewValue $ modelValue 。和它们之间的简单关系是这样的:

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

$解析器 $ viewValue 之间的合作和 $ modelValue 。所以,问题是,当你插入一个新的解析器 $解析器,修改后的值只会影响 $ modleValue ,你只需在解析函数返回一个新值。

$解析器是:


  

功能阵列来执行,作为管道,每当控制从DOM中读取值。该函数被调用数组顺序中,每过其返回值到下一个。最后一个返回值被转发到$验证集合


更多关于: https://docs.angularjs.org/api/纳克/类型/ ngModel.NgModelController#$ 解析器

而在解析器函数返回的值不会影响 $ viewValue ,所以你需要做的是也改变值与输入DOM元素体现

code例如:

  app.directive('形式',['$过滤',函数($过滤器){
    返回{
        要求:'ngModel',        链接:功能(范围,ELEM,ATTRS,CTRL){
            如果(CTRL!)回报;            Ctrl键。$ parsers.unshift(功能(viewValue){
                变种plainNumber = viewValue.replace(/ [^ \\ D | \\ - +] /克,'');
                //使用角内部'号'过滤器
                plainNumber = $过滤器(数字)(plainNumber / 100,2);                //更新$ viewValue
                CTRL $ setViewValue(plainNumber)。
                //反映DOM元素
                。CTRL $渲染();
                //返回修改后的值到下一个解析器
                返回plainNumber;
            });
        }
    };
}]);

一个工作plnkr是在这里: http://plnkr.co/edit/aoBWhJhlJLiEhBm5hRNX p = preVIEW

最后,为什么当你键入第6位,它消失的原因是:

当您输入6位数字,浏览器将转换并格式化您键入这种格式的号码:1,234.56(注意逗号,,分离器可以推迟对不同的浏览器),你会在控制台中看到由角发出警告:


  

指定的值1,234.56不是一个有效的数字。该值必须符合以下规律前pression: - ?(。\\ D + | \\ D + \\ D + | \\ D +)(?[EE] [ - +] \\ D +)


这是由从输入元素上键入='号',角将执行额外的内部验证,以匹配角度本身。定义的规则<限制造成的/ p>

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.

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, '');

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. only accept numbers, replace everything else with ''
  2. keep 2 decimal digits
  3. filter user's input and reflect/modify the value to the input element as user types

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:

input DOM value -> $viewValue -> $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 are :

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

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

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.

Code example:

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;
            });
        }
    };
}]);

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

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

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 :

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+)?

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.

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

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