问题
I'm building my first proper angular.js app after going through many tutorials. I've hit a problem with the ngChange
directive. I'm trying to use it to call a function each time the value of a drop down list is changed by the user. I find that it calls the function multiple times upon page load and also multiple times each time the option is selected.
I've put together this jsfiddle which demonstrates the problem I'm having.
I'd like to know why it's exhibiting this behaviour and how I can achieve my desired outcome of one function call per option change and no calling of change()
on page load. (this second criterion is less critical for my app, but I would like to know how to suppress this behaviour nonetheless).
I've reproduced the code below for those of you who may be able to find an immediate error.
HTML
<body ng-app ng-controller="Controller">
<div>
<h2>Number of changes: {{numOfChanges}}</h2>
<select ng-change="{{change()}}" ng-model="currentSelection">
<option ng-repeat="option in options">{{option}}</option>
</select>
</div>
</body>
JavaScript
Controller = function($scope) {
$scope.numOfChanges = 0;
$scope.change = function() {
$scope.numOfChanges++;
}
$scope.options = ["do", "ray", "me", "far", "so", "la", "tee","dah"]
}
I'm aware this could well be due to my improper use/understanding of the angular methodology. I'd appreciate answers that address all the failings of this small example.
回答1:
Anything inside ng-change is already recognised by angular, so you don't need to wrap it in {{ }}. Just ng-change="change()"
will do.
Wrapping it in braces will cause angular to evaluate it on page load and any time it updates the view, hence it firing multiple times.
回答2:
Remove {{ }}
from your ng-change()
code
<select ng-change="change()" ng-model="currentSelection">
{}
are in case of the bindings so you are firing change event so binding is not there.
You better look at this ngChange documentation
Updated Fiddle
回答3:
The answers of DKM and jonnyynnoj already explain what you have to do to make the ng-change work.
The reason why in your example the change listener is firing 10 times is because the "digest" cycle is updating 10 times and then aborting as explained here: http://docs.angularjs.org/api/ng.$rootScope.Scope#$digest
The $digest() is called directly by AngularJS. Here is the explanations from the docs which explains it:
Processes all of the watchers of the current scope and its children. Because a watcher's listener can change the model, the $digest() keeps calling the watchers until no more listeners are firing. This means that it is possible to get into an infinite loop. This function will throw 'Maximum iteration limit exceeded.' if the number of iterations exceeds 10.
In the javascript developer console you can also see that your example throws the following error: Error: 10 $digest() iterations reached. Aborting!
来源:https://stackoverflow.com/questions/17785617/why-is-angular-js-calling-my-function-so-frequently-with-ng-change-and-how-do-i