Say I have the following directive:
myApp.directive('myDirective', function() {
return {
restrict: 'A',
require: 'ngModel',
scope: {
ngModel: '='
},
link: function(scope, elem, attrs, ngModelCtrl) {
scope.$watch('ngModel', function() {
ngModelCtrl.$modelValue = 'foo';
});
}
}
});
And the following html:
<input ng-model="name" my-directive></input>
Basically, whenever the user changes the input, my-directive
would ideally change the internal model value to "foo" while leaving the view value untouched.
But when I print out $scope.name
in the corresponding controller, it doesn't log "foo", it logs whatever the user entered in.
It would seem that ngModelCtrl.$modelValue
is not what the controller is accessing -- am I approaching this problem incorrectly?
(Also watching the ngModel
in the scope feels really wrong, but I'm not sure of any other way. Any suggestions would be much appreciated!)
If you are looking for view change, you should never register a watch. ngModelController's $viewChangeListeners
are specifically designed for this purpose and to avoid creating any additional watch on the ngModel. You can also remove 2 way binding set up on the ngModel.
I can think of this way.
.directive('myDirective', function($parse) {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attrs, ngModelCtrl) {
/*Register a viewchange listener*/
ngModelCtrl.$viewChangeListeners.push(function(){
/*Set model value differently based on the viewvalue entered*/
$parse(attrs.ngModel).assign(scope, ngModelCtrl.$viewValue.split(','));
});
}
}
});
While thinking about it the other way around (Credits @Cody) it becomes more concise and appropriate while using a $parser
.
ngModelCtrl.$parsers.push(function(val) { return val.split(',') });