Angular JS: get ng-model on ng-change
Just for anyone else coming here,
ng-change
is actually called after the model value has been set.
Why?
Let's see when is it called.
From the angular source code, ng-change
is just an attribute directive with this directive definition object (DDO).
{
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attr, ctrl) {
ctrl.$viewChangeListeners.push(function() {
scope.$eval(attr.ngChange);
});
}
}
From this we see that the ng-change
directive is very simple. All that ng-change='<expr>'
does is add a function to the end of $viewChangeListeners
that evaluates <expr>
via $scope.$eval.
OK ... so when are the ViewChangeListeners called?
Well, if we look at the documentation for ngModel.NgModelController:
the new value will be applied to $modelValue and then the expression specified in the ng-model attribute. Lastly, all the registered change listeners, in the $viewChangeListeners list, are called.
So the viewChangeListener for the ngChange will be invoked after the value is applied to $modelValue
. Hence the callback will be invoked after the model as been set.
Also note that this behavior is the same in all versions of angular. The definition for ng-change
hasn't changed since v1.2.
The ng-change
handler is fired before the ng-model
is actually updated. If you want filterByCountry
to be fired every time $scope.country
changes (rather than just when the dropdown changes), you should use the following instead:
$scope.$watch('country', filterByCountry);
I always find it more useful to react to changes in my $scope
rather than DOM events when possible.