我有一些自定义验证码,其中包括一个$ formatter。 (我存储货币在便士的正确性,但显示在磅。)
如果用户在输入中输入“10”(这是一个有效值),则在输入到下一个字段后,输入将保持显示“10”。
我想要显示10.00的一致性。
如果模型将值更改为1000,则格式化程序将使字段显示“10 .00”。
我希望格式化程序在field.blur()(只要输入有效)上运行。
我的问题是,如果我将模型值从10改为10,那么可以理解的是没有任何变化,因此该字段不会被重新呈现。
码:
var CURRENCY_REGEXP = /^\-?\d+(\.?\d?\d?)?$/; app.directive('currency',function() { return { require: 'ngModel',link: function(scope,elm,attrs,ctrl) { ctrl.$parsers.unshift(function(viewValue) { if (CURRENCY_REGEXP.test(viewValue)) { // it is valid ctrl.$setValidity('currency',true); console.log("valid"); return viewValue * 100; } else if (viewValue === '') { return 0; } else { // it is invalid,return undefined (no model update) ctrl.$setValidity('currency',false); console.log("invalid"); return undefined; } }); ctrl.$formatters.push(function(modelValue) { if (modelValue === 0) { // we're using integer pence,so this is safe return ''; } return (modelValue / 100).toFixed(2); }); } }; });
附:这与Angular的内在“货币”无关。
更新:我已经按照Andy的答案添加了一个’renderOnBlur’指令。它被调用,但调用render方法不会重新渲染输入。即“10”保持为“10”,而不是根据需要变为“10 .00”。
(当这些字段中的模型值更改时,它们将以2位小数位正确呈现。)
Andy提到http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController的页面说你必须实现$ render自己。这似乎是奇怪的,因为当模型值改变时,输入已经正确显示。
app.directive('renderOnBlur',function() { return { require: 'ngModel',restrict: 'A',ctrl) { elm.bind('blur',function() { console.log('rendering ctrl',ctrl); ctrl.$render(); }); } }; });
附:我不知道有什么限制:“A”,真的是真正的货物编织计划在最糟糕的时候。需要:’ngModel’,似乎需要填充ctrl参数。
灵感来自@Dan Doyen的答案,我重写了:
app.directive('renderOnBlur',function() { var viewValue = ctrl.$modelValue; for (var i in ctrl.$formatters) { viewValue = ctrl.$formatters[i](viewValue); } ctrl.$viewValue = viewValue; ctrl.$render(); }); } }; });
这对于任何$ formatter都是通用的,而不是像Dan的答案那样重复格式化程序代码。
然而,您的控制器的$ modelValue正在正确更新,但由于模糊事件发生在角度之外,似乎您的$ viewValue不是。这个怎么样?
elm.bind('blur',function() { ctrl.$viewValue = (ctrl.$modelValue / 100).toFixed(2); ctrl.$render(); });