angularjsangularjs-directiveangularjs-digesttwo-way-binding

How does AngularJS implement two-way `'='` binding in its directives


How does AngularJS making bind by reference in its directives?

Sometimes when i pass variable by reference using '=' in my directive, and update the referenced variable in the parent controller, it does not get updated instantly, but it gets updated after making $scope.$digest().

what i think is that angular doesn't make reference binding like JS binding, but when the scope digest its just update its referenced variables.

i don't know if my theory is right.

what do you think?


Solution

  • The AngularJS $compile service implements two-way '=' binding by adding a watcher:

    var parentValueWatch = function parentValueWatch(parentValue) {
      if (!compare(parentValue, destination[scopeName])) {
        // we are out of sync and need to copy
        if (!compare(parentValue, lastValue)) {
          // parent changed and it has precedence
          destination[scopeName] = parentValue;
        } else {
          // if the parent can be assigned then do so
          parentSet(scope, parentValue = destination[scopeName]);
        }
      }
      lastValue = parentValue;
      return lastValue;
    };
    
    parentValueWatch.$stateful = true;
    if (definition.collection) {
      removeWatch = scope.$watchCollection(attrs[attrName], parentValueWatch);
    } else {
      removeWatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal);
    }
    removeWatchCollection.push(removeWatch);
    

    — GitHib AngularJS compile.js Source Code

    The watcher checks to see if the parent scope property is out of sync with the isolate scope property and updates as necessary. This means that the isolate scope is only updated after a digest cycle.