最近项目上使用了比较多的angular JS,一直都对它感受比较陌生,总以为有点反直觉,这段时间,准备下定决心弄明白,这个框架究竟是怎么一回事,以及它的工做原理,生命周期……一点一点的啃完它吧。首先,让咱们先来看看$watch、$digest、$apply这三个方法吧!html
Param | Type | Details |
watchExpression | function()angularjs stringexpress |
Expression that is evaluated on each $digest cycle. A change in the return value triggers a call to the listener.
|
listener (optional) |
function()api string 浏览器 |
Callback called whenever the return value of the watchExpressionchanges.
|
objectEquality (optional) |
boolean | Compare object for equality rather than for reference. |
从表格中能够看到,watchExpression和listener能够是一个string,也能够是一个function(scope)。该表达式在每次调用了$digest方法以后都会从新算值,若是返回值发生了改变,listener就会执行。在判断newValue和oldValue是否相等时,会递归的调用angular.equals方法。在保存值以备后用的时候调用的是angular.copy方法。listener在执行的时候,可能会修改数据从而触发其余的listener或者本身直到没有检测到改变为止。Rerun Iteration的上限是10次,这样可以保证不会出现死循环的状况。
$watch的基本结构以下:app
//$scope.$watch(<function/expression>, <handler>); $scope.$watch('foo', function(newVal, oldVal) { console.log(newVal, oldVal); }); //or $scope.$watch(function() { return $scope.foo; }, function(newVal, oldVal) { console.log(newVal, oldVal); });
该方法会触发当前scope以及child scope中的全部watchers,由于watcher的listener可能会改变model,因此$digest方法会一直触发watchers直到再也不有listener被触发。固然这也有可能会致使死循环,不过angular也帮咱们设置了上限10!不然会抛出“Maximum iteration limit exceeded.”。
一般,咱们不在controller或者directive中直接调用$digest方法,而是调$apply方法,让$apply方法去调用$digest方法。
如何调用该方法呢?框架
$scope.$digest();
Param | Type | Details |
exp (optional) |
string异步 function() ide |
An angular expression to be executed.
|
我的理解,$apply方法就是将$digest方法包装了一层,exp是可选参数,能够是一个string,也能够是function(scope)。伪代码(来自官方文档)以下:测试
function $apply(expr) { try { return$eval(expr); } catch(e) { $exceptionHandler(e); } finally { $root.$digest(); } }
$apply方法使得咱们能够在angular里面执行angular框架以外的表达式,好比说:浏览器DOM事件、setTimeout、XHR或其余第三方的库。因为咱们要在angular框架内调用,咱们必须得准备相应的scope。调用方式以下:
$scope.$apply('foo = "test"'); //or $scope.$apply(function(scope) { scope.foo = 'test'; }); //or $scope.$apply(function(){ $scope.foo = 'test'; });
至于angular js为何要这么作,请看我上一篇博客angular js之scope.$apply方法。
===============================================================================
该方法支持value types,regular expressions、arrays、objects。官方文档写的很清楚:
Two objects or values are considered equivalent if at least one of the following is true:
During a property comparison, properties of function type and properties with names that begin with $ are ignored.
Scope and DOM Window objects are being compared only by identify (===).