AngularJS $digest and $watch


Example

Implementing two-way-data-binding, to achieve the result from the previous example, could be done with two core functions:

  • $digest is called after a user interaction (binding DOM=>variable)
  • $watch sets a callback to be called after variable changes (binding variable=>DOM)

note: this is example is a demonstration, not the actual angular code


<input id="input"/>
<span id="span"></span>

The two functions we need:

var $watches = [];
function $digest(){
    $watches.forEach(function($w){
        var val = $w.val();
        if($w.prevVal !== val){
            $w.callback(val, $w.prevVal);
            $w.prevVal = val;
        }
    })
}
function $watch(val, callback){
    $watches.push({val:val, callback:callback, prevVal: val() })
}

Now we could now use these functions to hook up a variable to the DOM (angular comes with built-in directives which will do this for you):

var realVar;    
//this is usually done by ng-model directive
input1.addEventListener('keyup',function(e){
    realVar=e.target.value; 
    $digest()
}, true);

//this is usually done with {{expressions}} or ng-bind directive
$watch(function(){return realVar},function(val){
    span1.innerHTML = val;
});

Off-course, the real implementations are more complex, and support parameters such as which element to bind to, and what variable to use

A running example could be found here: https://jsfiddle.net/azofxd4j/