How does data binding work in AngularJS?

前端 未结 14 1514
情话喂你
情话喂你 2020-11-21 05:41

How does data binding work in the AngularJS framework?

I haven\'t found technical details on their site. It\'s more or less clear how it works when data

14条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-11-21 06:17

    Obviously there is no periodic checking of Scope whether there is any change in the Objects attached to it. Not all the objects attached to scope are watched . Scope prototypically maintains a $$watchers . Scope only iterates through this $$watchers when $digest is called .

    Angular adds a watcher to the $$watchers for each of these

    1. {{expression}} — In your templates (and anywhere else where there’s an expression) or when we define ng-model.
    2. $scope.$watch(‘expression/function’) — In your JavaScript we can just attach a scope object for angular to watch.

    $watch function takes in three parameters:

    1. First one is a watcher function which just returns the object or we can just add an expression.

    2. Second one is a listener function which will be called when there is a change in the object. All the things like DOM changes will be implemented in this function.

    3. The third being an optional parameter which takes in a boolean . If its true , angular deep watches the object & if its false Angular just does a reference watching on the object. Rough Implementation of $watch looks like this

    Scope.prototype.$watch = function(watchFn, listenerFn) {
       var watcher = {
           watchFn: watchFn,
           listenerFn: listenerFn || function() { },
           last: initWatchVal  // initWatchVal is typically undefined
       };
       this.$$watchers.push(watcher); // pushing the Watcher Object to Watchers  
    };
    

    There is an interesting thing in Angular called Digest Cycle. The $digest cycle starts as a result of a call to $scope.$digest(). Assume that you change a $scope model in a handler function through the ng-click directive. In that case AngularJS automatically triggers a $digest cycle by calling $digest().In addition to ng-click, there are several other built-in directives/services that let you change models (e.g. ng-model, $timeout, etc) and automatically trigger a $digest cycle. The rough implementation of $digest looks like this.

    Scope.prototype.$digest = function() {
          var dirty;
          do {
              dirty = this.$$digestOnce();
          } while (dirty);
    }
    Scope.prototype.$$digestOnce = function() {
       var self = this;
       var newValue, oldValue, dirty;
       _.forEach(this.$$watchers, function(watcher) {
              newValue = watcher.watchFn(self);
              oldValue = watcher.last;   // It just remembers the last value for dirty checking
              if (newValue !== oldValue) { //Dirty checking of References 
       // For Deep checking the object , code of Value     
       // based checking of Object should be implemented here
                 watcher.last = newValue;
                 watcher.listenerFn(newValue,
                      (oldValue === initWatchVal ? newValue : oldValue),
                       self);
              dirty = true;
              }
         });
       return dirty;
     };
    

    If we use JavaScript’s setTimeout() function to update a scope model, Angular has no way of knowing what you might change. In this case it’s our responsibility to call $apply() manually, which triggers a $digest cycle. Similarly, if you have a directive that sets up a DOM event listener and changes some models inside the handler function, you need to call $apply() to ensure the changes take effect. The big idea of $apply is that we can execute some code that isn't aware of Angular, that code may still change things on the scope. If we wrap that code in $apply , it will take care of calling $digest(). Rough implementation of $apply().

    Scope.prototype.$apply = function(expr) {
           try {
             return this.$eval(expr); //Evaluating code in the context of Scope
           } finally {
             this.$digest();
           }
    };
    

提交回复
热议问题