Money在Angular中格式化指令 [英] Money formatting directive in Angular

查看:126
本文介绍了Money在Angular中格式化指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



需要:

$ b我需要一个过滤货币字段的指令,所以用户只需要键入并且隐含小数。
$ b


  1. 将十进制字段设置为用户类型 -

    $ b 开始在用户输入的百分之一位置。所以他们会输入4,看到0.04,输入42,看到0.42,输入298023,然后看2980.23


    1. 字段必须是数字

    2. 必须允许负数 -

    3. 允许使用0.00作为数字输入

    4. 理想的情况是使用type =number,但是type = text可以。应该可以清除该字段为空。

    ng货币筛选器并不符合这些要求。请参阅深入了解我的意思。



    我的 First Plunker 有`input = text',允许负数。一个问题是,你不能输入一个负数作为第一个数字。当清除该字段时,它将返回到0.00,但应完全清除。



    pre $ app.directive('format',函数(scope,elem)['$ filter',function($ filter){
    return {
    require:'ngModel',//在html
    链接中必须有ng- ,attr,ctrl){
    if(!ctrl)return;

    ctrl。$ parsers.unshift(function(viewValue,modelValue){
    var plainNumber = viewValue.replace / [^ - + 0-9] / g,'');
    var newVal = plainNumber.charAt(plainNumber.length-1);
    var positive = plainNumber.charAt(0)!=' - ';
    if(isNaN(plainNumber.charAt(plainNumber.length-1))){
    plainNumber = plainNumber.substr(0,plainNumber.length-1)
    }
    //使用角度内部的数字过滤器
    plainNumber = $ filter('nu mber')(plainNumber / 100,2).replace(/,/ g,'');
    if(positive& newVal ==' - '){
    plainNumber =' - '+ plainNumber;

    else if(!positive&& newVal =='+'){
    plainNumber = plainNumber.substr(1);
    }
    plainNumber.replace('。',',');

    //更新$ viewValue
    ctrl。$ setViewValue(plainNumber);
    //反映DOM元素
    ctrl。$ render();
    //将修改后的值返回给下一个解析器
    return plainNumber;
    });
    }
    };

    }]);

    我的 Second Plunker input = text 并允许负面的输入。就像第一个擒纵器一样,只有在输入数字之后,它才不会让第一个字符成为负数。第二个是从十分之一开始,而不是百分之一。 (如果你输入'3',你应该看到'0.03',但这里显示'0.3')

    pre $ app code $ app.directive(' inputRestrictor',函数(){
    返回{
    restrict:'A',
    require:'ngModel',
    link:function(scope,element,attr,ngModelCtrl) {
    var pattern = /[^.0-9+-]/g;

    函数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,'');
    transformedInput = transformedInput.replace(/([0-9] {1,2} $)/,。$ 1)
    ngModelCtrl。$ setViewValue(transformedInput);
    ngModelCtrl。$ render();
    return transformedInput;
    }

    ngModelCtrl。$ parsers.push(fromUser);
    }
    };
    }]);

    如何协调这些解决方案或定制满足要求的解决方案?我想避免额外的库或附加组件。我被告知,最好的方法是研究货币过滤器的来源,并重新创建具有额外要求的过滤器。我希望这样做,但我现在真的没有这方面的技能。这两个指令是我所拥有的。

    解决方案

    。:: Updated Answer - July 14 ::。






    检查这个简单指令:

      app.directive('price',[ function(){
    return {
    require:'ngModel',
    link:function(scope,element,attrs,ngModel){
    attrs。$ set('ngTrim', false);

    var formatter = function(str,isNum){$ b $ str = String(Number(str || 0)/(isNum?1:100));
    str =(str =='0'?'0.0':str).split('。');
    str [1] = str [1] ||'0';
    return str [0] .replace(/(\ d)(?=(\ d \d\d)+(?!\d))/ g,'$ 1,')+'。'+( str [1] .length == 1 str [1] +'0':str [1]);
    }
    var updateView = function(val){$ b $ scope。$ applyAsync (function(){
    ngModel。$ setViewValue(val ||'');
    ngModel。$ render();
    });
    }
    var parseNumber = function(val){
    var modelString = formatter(ngModel。$ modelValue,true);
    var sign = {
    pos:/[+]/.test(val),
    neg:/[-]/.test(val)
    }
    sign.has = sign.pos || sign.neg;
    sign.both = sign.pos&& sign.neg;

    if(!val || sign.has&& val.length == 1 || ngModel。$ modelValue&& Number(val)=== 0){
    var newVal =(!val || ngModel。$ modelValue&& Number()=== 0?'':val);
    if(ngModel。$ modelValue!== newVal)
    updateView(newVal);

    return'';
    }
    else {
    var valString = String(val ||'');
    var newSign =(sign.both& ngModel。$ modelValue> = 0 ||!sign.both&&&sign.neg?' - ':'');
    var newVal = valString.replace(/ [^ 0-9] / g,'');
    var viewVal = newSign + formatter(angular.copy(newVal));

    if(modelString!== valString)
    updateView(viewVal);

    return(Number(newSign + newVal)/ 100)|| 0;


    var formatNumber = function(val){
    if(val){
    var str = String(val).split('。');
    str [1] = str [1] || 0’ ;
    val = str [0] +'。'+(str [1] .length == 1?str [1] +'0':str [1]);
    }
    return parseNumber(val);
    }

    ngModel。$ parsers.push(parseNumber);
    ngModel。$ formatters.push(formatNumber);
    }
    };
    }]);

    然后像这样使用它:

     < input type =textng-model =numberprice> 

    看到它住在 PLUNKER (7月14日)

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

    Needs:

    1. Format decimal field as user types -

    Start at the hundredths place as the user types. So they would type "4" and see "0.04", type "42" and see "0.42", type 298023 and see "2980.23"

    1. Field must be a number
    2. Must allow negatives -
    3. Allow 0.00 as a number input
    4. Ideally would use type="number" but "type=text" is okay
    5. You should be able to clear the field to be empty.

    The ng-currency filter does not fulfill these requirements as is. Please see behaviour in plunkers to see what I mean.

    My First Plunker has `input = text' and allows negative numbers. One problem is that you cannot type a negative as the very first number. When you clear the field, it returns to '0.00' but it should completely clear.

       app.directive('format', ['$filter', function ($filter) {
     return {
                require: 'ngModel', //there must be ng-model in the html
                link: function (scope, elem, attr, ctrl) {
                    if (!ctrl) return;
    
                    ctrl.$parsers.unshift(function (viewValue, modelValue) {
                        var plainNumber = viewValue.replace(/[^-+0-9]/g,'');
                        var newVal = plainNumber.charAt(plainNumber.length-1);
                        var positive = plainNumber.charAt(0) != '-';
                        if(isNaN(plainNumber.charAt(plainNumber.length-1))){
                          plainNumber = plainNumber.substr(0,plainNumber.length-1)
                        }
                        //use angular internal 'number' filter
                        plainNumber = $filter('number')(plainNumber / 100, 2).replace(/,/g, '');
                        if(positive && newVal == '-'){
                          plainNumber = '-' + plainNumber;
                        }
                        else if(!positive && newVal == '+'){
                          plainNumber = plainNumber.substr(1);
                        }
                        plainNumber.replace('.', ',');
    
                        //update the $viewValue
                        ctrl.$setViewValue(plainNumber);
                        //reflect on the DOM element
                        ctrl.$render();
                        //return the modified value to next parser
                        return plainNumber;
                    });
                }
            };
    
    }]);
    

    My Second Plunker has input = text and allows for negative input. Like the first plunker, it won't allow a negative as the first character, only after numbers are typed. The second is that it starts at the tenths place instead of the hundredths. (if you type '3' you should see '0.03' but here it shows '0.3')

    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; // plus sign?
                        else text = "-" + text;
                    }
    
                    var transformedInput = text.replace(pattern, '');
                    transformedInput = transformedInput.replace(/([0-9]{1,2}$)/, ".$1")
                    ngModelCtrl.$setViewValue(transformedInput);
                    ngModelCtrl.$render();
                    return transformedInput;
                }
    
                ngModelCtrl.$parsers.push(fromUser);
            }
        };
    }]);
    

    How can I reconcile these solutions or tailor one to meet the requirements? I want to avoid extra libraries or add-ons. I have been told that the best approach would be to study the source for the currency filter, and recreate that filter with the additional requirements.I would love to do this, but I really don't have the skills for it right now. These two directives are what I have.

    解决方案

    .:: Updated Answer - July 14 ::.


    Check this simple directive:

    app.directive('price', [function () {
        return {
            require: 'ngModel',
            link: function (scope, element, attrs, ngModel) {
                attrs.$set('ngTrim', "false");
    
                var formatter = function(str, isNum) {
                    str = String( Number(str || 0) / (isNum?1:100) );
                    str = (str=='0'?'0.0':str).split('.');
                    str[1] = str[1] || '0';
                    return str[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,') + '.' + (str[1].length==1?str[1]+'0':str[1]);
                }
                var updateView = function(val) {
                    scope.$applyAsync(function () {
                        ngModel.$setViewValue(val || '');
                        ngModel.$render();
                    });
                }
                var parseNumber = function(val) {
                    var modelString = formatter(ngModel.$modelValue, true);
                    var sign = {
                        pos: /[+]/.test(val),
                        neg: /[-]/.test(val)
                    }
                    sign.has = sign.pos || sign.neg;
                    sign.both = sign.pos && sign.neg;
    
                    if (!val || sign.has && val.length==1 || ngModel.$modelValue && Number(val)===0) {
                        var newVal = (!val || ngModel.$modelValue && Number()===0?'':val);
                        if (ngModel.$modelValue !== newVal)
                            updateView(newVal);
    
                        return '';
                    }
                    else {
                        var valString = String(val || '');
                        var newSign = (sign.both && ngModel.$modelValue>=0 || !sign.both && sign.neg?'-':'');
                        var newVal = valString.replace(/[^0-9]/g,'');
                        var viewVal = newSign + formatter(angular.copy(newVal));
    
                        if (modelString !== valString)
                            updateView(viewVal);
    
                        return (Number(newSign + newVal) / 100) || 0;
                    }
                }
                var formatNumber = function(val) {
                    if (val) {
                        var str = String(val).split('.');
                        str[1] = str[1] || '0';
                        val = str[0] + '.' + (str[1].length==1?str[1]+'0':str[1]);
                    }
                    return parseNumber(val);
                }
    
                ngModel.$parsers.push(parseNumber);
                ngModel.$formatters.push(formatNumber);
            }
        };
    }]);
    

    And use it like this:

    <input type="text" ng-model="number" price >
    

    See it live in this PLUNKER (July 14)

    这篇关于Money在Angular中格式化指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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