I have a directive that basically watches the value of element.
This element has ng-maxlength
attribute which is set to 150. When I pass the 150 characters, the $watch
is no longer triggered. Besides, when I remove the whole text with ctrl + x, the $watch
is again not triggered.
Input Element
<input type="text" ng-model="company.fullName" name="companyFullName" required ng-maxlength="150" ng-input-validate />
Directive
enlabApp.directive('ngInputValidate', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ctrl) {
scope.$watch(function () { return ctrl.$modelValue; }, function (value) {
console.log('test');
});
}
};
});
When I remove the ng-maxlength
directive, the problem goes away.
You are using ng-maxlength=150
which mean angular will perform a validation for the number of characters and it will update the $modelValue
accordingly. Meaning when it is invalid (if length exceeds) $modelValue
will be undefined
and then you remove the value by doing ctl-x
and then digest cycle runs and again model value becomes undefined
since there is no value present and there is no difference from the previous value and the watcher does not trigger (Watcher will trigger only if the modelValue
becomes dirty).
So use $viewValue
or element[0].value
(which i wont suggest). So do:-
scope.$watch(function () {
return ctrl.$viewValue;
}, function (value) {
console.log('Triggered');
});
Remember that using ng-minlength
is only for validation it does not restrict user from entering/pasting more characters, if you want to restrict the minlength
attribute is the way to go
Also note that you do not have to register a watch on ngModel
you can use $viewChangeListeners
as well instead of creating an additional watch.
Array of functions to execute whenever the view value has changed. It is called with no arguments, and its return value is ignored. This can be used in place of additional $watches against the model value.
ctrl.$viewChangeListeners.push(function(){//... });