在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 这样的小数点,我需要按 '.'两次。这是为什么?无论如何要“解决”这个问题? 您将如何使用<input type="number">
来做到这一点?我试过了,但失败了: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中格式化输入值的主要内容,如果未能解决你的问题,请参考以下文章