I need to be able to temporarily persist data that isn\'t fully validated yet, then enforce validation when I\'m ready to make it permanent. But Angular is preventing that.
Emil van Galen has a blog post that covers exactly this issue. I've used his input directive, which works perfectly.
As he point out, The $parsers array of NgModelController is:
Array of functions to execute, as a pipeline, whenever the control reads value from the DOM. Each function is called, in turn, passing the value through to the next. Used to sanitize / convert the value as well as validation. For validation, the parsers should update the validity state using $setValidity(), and return undefined for invalid values.
So, to allow the model to be updated to an invalid value, yet retain the validation results, create a directive that does not return undefined
for invalid values. For example, Emil's directive reverts invalid, undefined string values to the model value, otherwise it returns the view value:
angular.module('jdFixInvalidValueFormatting', [])
.directive('input', function() {
return {
require: '?ngModel',
restrict: 'E',
link: function($scope, $element, $attrs, ngModelController) {
var inputType = angular.lowercase($attrs.type);
if (!ngModelController || inputType === 'radio' ||
inputType === 'checkbox') {
return;
}
ngModelController.$formatters.unshift(function(value) {
if (ngModelController.$invalid && angular.isUndefined(value)
&& typeof ngModelController.$modelValue === 'string') {
return ngModelController.$modelValue;
} else {
return value;
}
});
}
};
});
You can see it working in his Plunker (also note his take on an improved handling of null
rather than undefined
): http://plnkr.co/edit/gist:6674554?p=preview