最近項目上使用了比較多的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 (===).