AngularJS - 如何在我输入时在文本框上应用货币过滤器?
Posted
技术标签:
【中文标题】AngularJS - 如何在我输入时在文本框上应用货币过滤器?【英文标题】:AngularJS - How to apply currency filter on textbox as I type? 【发布时间】:2014-05-21 09:46:25 【问题描述】:我的项目需要以货币格式显示金额字段。我可以实现这个onblur
事件,但是让我知道这是否可以使用过滤器或其他一些 AngularJS 技术来实现。
我有以下文本框:
<input type="text" class="form-control" id="MyAmount" name="MyAmount" ng-model="MyAmount" />
我想将此文本框中的值转换为货币格式。因此,如果我输入 200,000,那么在我输入时或在输入时它应该是 $200,000.00。
我使用了以下技术并应用了过滤器,
<input type="text" class="form-control" id="MyAmount" name="MyAmount" ng-model="MyAmount"
value="MyAmount | currency" />
但它只转换我输入的第一个键,就像它将 2 转换为 $2.00 然后它清除值(因为我猜它发现这个更新的值不是数字?)
更新:我可以使用自定义过滤器对其进行实时格式化,但该过滤器在所有情况下都无法正常工作,当我保存该值时,我得到的值中包含 $ 和逗号,而不仅仅是数值。我会尝试更多。
【问题讨论】:
【参考方案1】:这是一个相当重要的问题。
对于功能的主要部分,您需要使用ngModelController
的$formatters
和$parsers
属性来注册监听器以分别处理$modelValue
和$viewValue
的变化。
当$modelValue
发生变化时,您需要先使用currency
过滤器对其进行过滤,然后再将其显示到视图中。
当$viewValue
发生变化时,您需要将其转换为数字(我认为将模型值存储为数字而不是格式化字符串更有意义),通过@987654332 过滤该数字@过滤并更新$viewValue
(如有必要)。
这并不是特别困难。棘手的部分是更新元素的值,将光标移动到末尾,因此您需要手动重新定位插入符号。
我的尝试导致了以下指令定义对象
restrict: 'A',
require: 'ngModel',
link: function postLink(scope, elem, attrs, modelCtrl)
modelCtrl.$formatters.push(filterFunc);
modelCtrl.$parsers.push(function (newViewValue)
var newModelValue = toNumber(newViewValue);
modelCtrl.$viewValue = filterFunc(newModelValue);
var pos = getCaretPosition(elem[0]);
elem.val(modelCtrl.$viewValue);
var newPos = pos + modelCtrl.$viewValue.length -
newViewValue.length;
setCaretPosition(elem[0], newPos);
return newModelValue;
);
;
另请参阅此short demo。它并不完美,但它是一个好的开始。
顺便说一句,我从 AngularUI 的 uiMask
指令中“借用”了get/setCaretPosition()
函数。
【讨论】:
谢谢,现在我对我应该做什么有了更好的理解。我会尝试你的解决方案。但是该演示仅采用单个数字值,例如 $2.00 等。我必须手动将光标移动到小数点之前,然后再次键入以输入更多数字。请看一看。我正在使用最新版本的 Chrome。 我不明白你的意思。我可以输入任何数字(例如:对于$2,123.00
,我将光标放在小数点分隔符之前并输入2
、1
、2
、3
)。你到底什么意思 ? (我也在 Windows 上使用最新版本的 Chrome。)
是的,如果我将光标放在小数点分隔符之前,它可以完美运行。但我的文本框最初是空白的,我将从空白开始输入。在您的演示中,我可以从空白值开始吗?谢谢。
一切皆有可能。你只需要实现它:) 查看我更新的小提琴。就像我说的,这不是最终的解决方案,但它是一个很好的陈述点。但是您必须根据您的具体要求对其进行修改。 (如果它帮助您解决了问题,请不要忘记访问答案。)
@RafaelMerlin:事情就是这样工作的:) 为$viewValue
分配新值不会自动设置元素的值。通常,你会调用$render()
,但这是一种特殊情况,因为我们要捕获并重置插入符号的位置,所以我们必须手动进行(或覆盖控制器的$render()
方法)。【参考方案2】:
您还可以使用自动为您提供此功能的fcsa-number 指令。就像将fcsa-number
属性添加到输入元素一样简单。
<input type="text" fcsa-number />
还有here is a demo
源代码和文档在 GitHub 上可用:https://github.com/FCSAmericaDev/angular-fcsa-number
【讨论】:
【参考方案3】:我在尝试构建自定义货币指令时遇到了同样的问题。因此,在检查了许多解决方法后,我找到了angular-input-masks 指令。
支持 bower 快速安装和使用只需在输入文本元素上添加 ui-money-mask 属性:
<input type="text" ng-model="money" ui-money-mask>
还支持最小值和最大值验证。
【讨论】:
angular-input-masks 唯一的问题是它不自动调整光标,也不支持设置动态 $locale。 有问题的解决方案。以上是关于AngularJS - 如何在我输入时在文本框上应用货币过滤器?的主要内容,如果未能解决你的问题,请参考以下文章
成功完成初始自动完成后,如何在 WinForm 文本框上重新启动自动完成?