【问题标题】:Format input value in Angularjs在Angularjs中格式化输入值
【发布时间】:2013-11-22 07:27:44
【问题描述】:

我正在尝试编写一个指令来自动格式化<input> 中的数字,但模型未格式化。 让它工作很好,加载时输入中的值在控制器中显示为 1,000,000 和 1000000,但是当只输入 ngModel.$parsers 函数时会触发。 ngModel.$formatters 触发的唯一时间是指令被加载且值为 0 时。

我怎样才能让它在按键上工作(我已经尝试绑定到 keypress/keyup 但它不起作用)。

这是我的代码:

angular.module('myApp.directives', []).directive('filterInput', ['$filter', function($filter) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attr, ngModel) {

            ngModel.$parsers.push(function fromUser(text) {
                return parseInt(text.replace(",", ""));
            });

            ngModel.$formatters.push(function toUser(text) {
                console.log($filter('number')(text));
                return ($filter('number')(text || ''));
            });

        }
    };
}]);

【问题讨论】:

    标签: javascript jquery angularjs input


    【解决方案1】:

    这是我们使用unshift的工作示例:

    angular.module('myApp.directives', []).directive('format', ['$filter', function ($filter) {
        return {
            require: '?ngModel',
            link: function (scope, elem, attrs, ctrl) {
                if (!ctrl) return;
    
    
                ctrl.$formatters.unshift(function (a) {
                    return $filter(attrs.format)(ctrl.$modelValue)
                });
    
    
                ctrl.$parsers.unshift(function (viewValue) {
                    var plainNumber = viewValue.replace(/[^\d|\-+|\.+]/g, '');
                    elem.val($filter(attrs.format)(plainNumber));
                    return plainNumber;
                });
            }
        };
    }]);
    

    HTML 看起来:

    <input type="text" ng-model="test" format="number" />
    

    查看演示Fiddle

    希望对你有所帮助

    【讨论】:

    • 如果我想添加像 150.33 这样的小数点,我需要按 '.'两次。这是为什么?无论如何要“解决”这个问题?
    • 您将如何使用&lt;input type="number"&gt; 来做到这一点?我试过了,但失败了:jsfiddle.net/SAWsA/3957
    • 我喜欢你所做的解决方案,我有一个问题是有一个表达式可以替换为“。”(点)而不是“,”(逗号),因为它在欧洲的默认值是“.”(点)是千位分隔符,“,”(逗号)是小数分隔符?
    • @Clark -- push 放在数组的 end 上,unshift 放在数组的 start 上。 Order is important 因为 $parsers,函数是“按数组顺序”执行的,但 $formatters 是“按 reverse 数组顺序”执行的。
    • 当您连续两次键入相同的字母时,它确实会失败。您可以看到解析不会触发的字母表。
    【解决方案2】:

    这个模块对我来说很好用。

    https://github.com/assisrafael/angular-input-masks

    例子:

    <input type="text" name="field" ng-model="number" ui-number-mask>
    

    【讨论】:

    • 看起来不错,尽管它使用了与接受的答案中描述的相同的方法。当问题被问到时,这也不存在。
    【解决方案3】:

    根据此问题的答案,对以下 Maxim Soustin 的答案进行小幅编辑: AngularJS formatter - how to display blank instead of zero

    唯一的改变是确保在删除最后一个数字时输入是空白而不是零:

       ctrl.$parsers.unshift(function (viewValue) {
            console.log(viewValue);
            if(viewValue){
                var plainNumber = viewValue.replace(/[^\d|\-+|\.+]/g, '');
                elem.val($filter('number')(plainNumber));
                return plainNumber;
            }else{
                return '';
            }
        });
    

    http://jsfiddle.net/2n73j6rb/

    【讨论】:

    【解决方案4】:

    我为自己创建了这个指令解决方案:

    1. 在焦点上将输入初始化为 0.00。
    2. 与模板驱动和 ReactiveForm 兼容。
    3. 删除/撤消任何非数字条目。
    4. 防止空输入。
    5. 粘贴 123ab4d5,输出:12345。
    6. 每千除以一个,
    7. 退格/删除兼容。
    8. 让我们在中间输入/删除。
    9. 仅正整数。

    推荐:使用 [maxLength] 将用户限制在一定长度内。

     <input [maxLength]="9" appPriceUsd>
    

    指令如下:

    // Format USD by Reza Taba
    import { DecimalPipe } from '@angular/common';
    import { Directive, ElementRef, HostListener } from '@angular/core';
    
    
    @Directive({
      selector: '[appPriceUsd]'
    })
    export class PriceUsdDirective {
      constructor(private elRef: ElementRef, private decimalPipe: DecimalPipe) { }
    
      @HostListener('focus') initializeValue(): void {
        if (this.elRef.nativeElement.value === '') {
          this.elRef.nativeElement.value = '0.00';
        }
      }
    
      @HostListener('keyup') formatUsd(): void {
        let value: string;
        value = this.elRef.nativeElement.value as string;
        value = this.removeNonDigtis(value); // remove all non-digit values
        value = this.addDecimalPoint(value); // Add . to the -2 index
        value = this.applyDecimalPipe(value); // to divide every thousand
        this.elRef.nativeElement.value = value;
      }
    
      removeNonDigtis(value: string): string {
        let inputArray: string[] = [];
        const digitArray: string[] = [];
    
        // 12a34b to ["1", "2", "a", "3", "4", "b"]
        inputArray = value.split('');
    
        // remove any non-digit value
        for (const iterator of inputArray) {
          if (/[0-9]/.test(iterator)) {
            digitArray.push(iterator);
          }
        }
    
        return digitArray.join('');
      }
    
      addDecimalPoint(value: string): string {
        const inputArray = value.split(''); // ['0', '.', '0', '0']
        inputArray.splice(-2, 0, '.'); // place decimal in -2
        return inputArray.join('');
      }
    
      applyDecimalPipe(value: string): string {
        console.log(value);
        return value === '' || value === '.'
          ? '0.00'
          : this.decimalPipe.transform(value, '1.2-2');
      }
    }
    

    希望对您有所帮助。享受编码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-23
      • 2013-07-09
      • 1970-01-01
      • 2015-06-07
      • 2021-01-05
      • 1970-01-01
      相关资源
      最近更新 更多