Why is Angular.js calling my function so frequently with ng-change and how do I make it call only once per change?

我们两清 提交于 2019-12-10 18:16:25

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!