在Angularjs中格式化输入值

Posted

技术标签:

【中文标题】在Angularjs中格式化输入值【英文标题】:Format input value in 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 || ''));
            );

        
    ;
]);

【问题讨论】:

【参考方案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/

【讨论】:

如果我从 $scope.test = ''; 开始我仍然得到0。如何从空白输入框开始? jsfiddle.net/magician11/947cb12h【参考方案4】:

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

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

推荐:使用 [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');
  

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

【讨论】:

以上是关于在Angularjs中格式化输入值的主要内容,如果未能解决你的问题,请参考以下文章

对angularjs时间过滤格式

AngularJS-03 过滤器

angularjs:无法在数字类型的输入字段中显示特殊字符

angularjs将值附加到内部数组中

你能用 AngularJS 做条件格式化吗?

angularjs 判断字符串是不是是数字格式