У меня есть пользовательский код проверки, который включает форматирование $. (Я сохраняю валюту в пенсах для корректности, но отображаю в фунтах.)
Если пользователь вводит «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);
});
}
};
});
P.S. Это не имеет ничего общего со встроенным -Angular в «валюте».
Обновление :Я добавил директиву «renderOnBlur», согласно ответу Энди. Он вызывается, но вызов метода рендеринга не приводит -к рендерингу ввода. т. е. «10» остается как «10», а не меняется на «10,00» по желанию.
(Когда значение модели изменяется в этих полях, они правильно отображаются с двумя десятичными знаками.)
Страница, которую упоминает Эндиhttp://docs.angularjs.org/api/ng.directive:ngModel.NgModelControllerговорит, что вы должны реализовать $render
самостоятельно. Это кажется странным, так как входные данные уже отображаются правильно, когда значение модели изменяется.
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. Я понятия не имею, что restrict: 'A',
делает -это настоящий груз -культовое программирование в худшем его проявлении. require: 'ngModel',
кажется необходимым для заполнения параметра ctrl
.
Вдохновленный ответом @Dan Doyen, я переписал его как:
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();
});
}
};
});
Преимущество этого заключается в том, что он является универсальным для любого $formatter, а не повторяет код форматирования, как в ответе Дэна.