问题描述
我有一些自定义的验证code,其中包括$格式化。 (我店货币便士正确性,但是pounds.pence显示。)
I have some custom validation code, which includes a $formatter. (I store currency in pence for correctness, but display in pounds.pence.)
如果用户键入10到输入(这是一个有效的值)时,输入仍然显示10后,便转移到下一个字段。
If the user types '10' into the input (which is a valid value), the input remains displaying '10' after they move to the next field.
我想它的一致性显示10.00。
I would like it to display 10.00 for consistency.
如果模型改变了价值为1000,然后格式化会使得显示设备领域的'10 .00'。
If the model changed the value to 1000, then the formatter would make the field display '10.00'.
我想格式化就field.blur(运行)(只要输入有效)。
I would like the formatter to run on field.blur() (so long as the input is valid).
我的问题是,如果我改变从10到10的模型值,也可以理解为没有变化,所以现场没有重新呈现。
My problem is that if I change the model value from 10 to 10, there is understandably no change, and so the field is not re-rendered.
code:
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);
});
}
};
});
P.S。这有没有关系角度内置的货币。
P.S. This has nothing to do with Angular's built-in 'currency'.
更新:我添加了一个renderOnBlur'指令,按照安迪的回答。它被调用,但调用的渲染方法不会重新渲染输入。即,'10'保持为'10',而不是作为所需的改变到'10 .00'。
Update: I've added a 'renderOnBlur' directive, as per Andy's answer. It gets called, but calling the render method does not re-render the input. i.e. '10' stays as '10', rather than changing to '10.00' as desired.
(如果在这些领域的模型值的变化,它们正确渲染与2位小数)。
(When the model value changes in these fields, they are correctly rendered with the 2 decimal places.)
这安迪提到http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController说,你必须执行 $渲染
自己。这似乎有点奇怪,因为投入已经正确呈现在模型值的变化。
The page which Andy mentions http://docs.angularjs.org/api/ng.directive:ngModel.NgModelController says that you have to implement $render
yourself. This seems odd, as the inputs are already rendered correctly when the model value changes.
app.directive('renderOnBlur', function() {
return {
require: 'ngModel',
restrict: 'A',
link: function(scope, elm, attrs, ctrl) {
elm.bind('blur', function() {
console.log('rendering ctrl', ctrl);
ctrl.$render();
});
}
};
});
P.S。我不知道是什么限制:'A',
那样 - 这是在最坏的情况真实的货物邪教编程。在要求:ngModel,
似乎有必要来填充 CTRL
参数
P.S. I have no idea what restrict: 'A',
does - it's true cargo-cult programming at its worst. The require: 'ngModel',
seems necessary to populate the ctrl
parameter.
由@丹东银的回答启发,我重写它作为:
Inspired by the answer from @Dan Doyen, I rewrote it as:
app.directive('renderOnBlur', function() {
return {
require: 'ngModel',
restrict: 'A',
link: function(scope, elm, attrs, ctrl) {
elm.bind('blur', function() {
var viewValue = ctrl.$modelValue;
for (var i in ctrl.$formatters) {
viewValue = ctrl.$formatters[i](viewValue);
}
ctrl.$viewValue = viewValue;
ctrl.$render();
});
}
};
});
这有被仿制任何$格式,而不是重复格式化code作为于丹的回答的好处。
This has the benefit of being generic for any $formatter, rather than repeating the formatter code as in Dan's answer.
推荐答案
您控制器的$ modelValue正在更新正确的,但是,但由于模糊事件发生的角度之外,似乎你的$ viewValue不是。这个怎么样?
Your controller's $modelValue is being updated properly, however, but since the blur event is happening outside of angular, it seems your $viewValue is not. How about this?
elm.bind('blur', function() {
ctrl.$viewValue = (ctrl.$modelValue / 100).toFixed(2);
ctrl.$render();
});
这篇关于AngularJS如何强制输入上的模糊,以重新呈现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!