How exactly does the AngularJS Digest Loop work?

醉酒当歌 提交于 2019-12-20 07:16:09

问题


I am new to AngularJS and I am studying it on a tutorial. I have some doubt about the concept related to the Digest Loop provided by Angular.

My application is composed by these 2 files:

1) index.html:

<!DOCTYPE html>
<html lang="en-us" ng-app="myApp">
    <head>
        <title>Learn and Understand AngularJS</title>
        <meta http-equiv="X-UA-Compatible" content="IE=Edge">
        <meta charset="UTF-8">

        <!-- load bootstrap and fontawesome via CDN -->
        <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
        <style>
            html, body, input, select, textarea
            {
                font-size: 1.05em;
            }
        </style>

        <!-- load angular via CDN -->
        <script src="//code.angularjs.org/1.3.0-rc.1/angular.min.js"></script>
        <script src="app.js"></script>
    </head>
    <body>

        <header>
            <nav class="navbar navbar-default">
            <div class="container">
                <div class="navbar-header">
                    <a class="navbar-brand" href="/">AngularJS</a>
                </div>

                <ul class="nav navbar-nav navbar-right">
                    <li><a href="#"><i class="fa fa-home"></i> Home</a></li>
                </ul>
            </div>
            </nav>
        </header>

        <div class="container">

            <div ng-controller="mainController">

                <div>
                    <label>What is your twitter handle?</label>
                    <input type="text" ng-model="handle" />
                </div>

                <hr />

                <h1>twitter.com/{{ lowercasehandle() }}</h1>

            </div>

        </div>

    </body>
</html>

2) app.js:

var myApp = angular.module('myApp', []);

myApp.controller('mainController', ['$scope', '$filter', '$timeout', function($scope, $filter, $timeout) {

    // Variable that is bound to the input into the view handled by the 'mainController' controller:
    $scope.handle = '';

    // This variable is a function putted into the $scope and contain the lowecase content of the handle variable:
    $scope.lowercasehandle = function() {
        return $filter('lowercase')($scope.handle);
    };

    // I explicitly declare a whatche on the handle property: when the value of this propertu change the function() is performed:
    $scope.$watch('handle', function(newValue, oldValue) {

        console.info('Changed!');
        console.log('Old:' + oldValue);
        console.log('New:' + newValue);

    });

    $timeout(function() {

        $scope.handle = 'newtwitterhandle';
        console.log('Scope changed!');

    }, 3000);

}]);

From what I understand, the handle variable is declared into the Angular scope, by:

$scope.handle = '';

and it is automatically bound to a specific object of view as declared in this section of the DOM of index.html:

<div>
    <label>What is your twitter handle?</label>
    <input type="text" ng-model="handle" />
</div>

So any change that happen into this input object implies a change of the handle property in the $scope and vice-versa.

My understanding is that with Angular, I do not have to manually add a classic vanilla JavaScript EventListener (by the addEventListener() on the object that I want to observe) but Angular implements this feature for me using the Disgest Loop.

Then Angular (but I am not so sure about it) maintains a watcher list in the Angular Context. In this list there is a watcher object for each element in the scope that has been included in the page (input, select, etc).

So a watcher contains the information about the old value and the new value of the related element and if the new value is different from the old value Angular automatically update in the related field in the DOM.

From what I have understood the digest loop continuously iterates on this watcher list to check if the old value of a specific watcher is different from the new value (if the value of the observed object is changed).

So what it means exactly? That Angular continuously runs a cycle (something like a while) that continuously check if the value of some field is change? And if it happen automatically perform a specific operation?


回答1:


All your assertions are true, but the digest loop activity is not such a timer function that run always to find changes, but when you add an inplicit watcher (with ng-model or ng-bind) and somethings append on angular context (an input change, a click event ecc.) the digest loop start and apply changes to all active watcher. Is a loop because it run while the previous iteration mark some changes; it stop when there are no changes left or it interate more then 10 times (that mean some design problem).

This is the reason because to have too many watchers could cause performance issues.

A good example to understand that is to create a directive with the link function that change some model property. If you didn't enclose that change on a $apply function or you didn't call $digest the model change will not affect the model watchers.



来源:https://stackoverflow.com/questions/33693677/how-exactly-does-the-angularjs-digest-loop-work

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