I have the following HTML
<select ng-model="country" ng-options="c.name for c in countries" ng-change="filterByCountry"></select>
That is beeing fed by the following object with a list of countries
$scope.countries = [{name:Afeganistão, country:AF}, {name:África do Sul, country:ZA}, name:Albânia, country:AL}, {name:Alemanha, country:DE}, {name:Andorra, country:AD} ...];
When I change my dropdown value I was expecting my model ($scope.country) to be updated, inside filterByCountry function, but it isn't. What am I missing here?
Ng-change is a directive in AngularJS which is meant for performing operations when a component value or event is changed. In other words, ng-change directive tells AngularJS what to do when the value of an HTML element changes. An ng-model directive is required by the ng-change directive.
$watch() function is used to watch the changes of variables in $scope object. Generally the $watch() function will create internally in Angularjs to handle variable changes in application.
The ngInit directive allows you to evaluate an expression in the current scope. This directive can be abused to add unnecessary amounts of logic into your templates. There are only a few appropriate uses of ngInit : aliasing special properties of ngRepeat , as seen in the demo below.
There is no difference between ng-model and data-ng-model if you see in terms of AngularJs. Actually, 'data' used as prefix to validate HTML5 validation. So, it is good practice to use data-ng-model , however, you can use ng-model as well. There is no problem in that also.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With