I believe that the intention of AngularJS inputs and the ngModel
direcive is that invalid input should never end up in the model. The model should always be valid. The problem with having invalid model is that we might have watchers that fire and take (inappropriate) actions based on invalid model.
As I see it, the proper solution here is to plug into the $parsers
pipeline and make sure that invalid input doesn't make it into the model. I'm not sure how did you try to approach things or what exactly didn't work for you with $parsers
but here is a simple directive that solves your problem (or at least my understanding of the problem):
app.directive('customValidation', function(){
return {
require: 'ngModel',
link: function(scope, element, attrs, modelCtrl) {
modelCtrl.$parsers.push(function (inputValue) {
var transformedInput = inputValue.toLowerCase().replace(/ /g, '');
if (transformedInput!=inputValue) {
modelCtrl.$setViewValue(transformedInput);
modelCtrl.$render();
}
return transformedInput;
});
}
};
});
As soon as the above directive is declared it can be used like so:
<input ng-model="sth" ng-trim="false" custom-validation>
As in solution proposed by @Valentyn Shybanov we need to use the ng-trim
directive if we want to disallow spaces at the beginning / end of the input.
The advantage of this approach is 2-fold:
- Invalid value is not propagated to the model
- Using a directive it is easy to add this custom validation to any input without duplicating watchers over and over again
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…