我們經(jīng)常聽到angular的臟檢查機制和數(shù)據(jù)的雙向綁定,這兩個詞似乎已經(jīng)是它的代名詞了。那么從編程層面,這到底是什么鬼?
當$scope的一個屬性被改變時,界面可能會更新。那么為什么angular里面,修改$scope上的一個屬性,可以引起界面的變化呢?這是angular的數(shù)據(jù)響應機制決定的。在angular里面就是臟檢查機制。而臟檢查,和雙向綁定離不開。
這里插句題外話,JavaScript里面非常有意思的一種接口,當你修改(或新增)一個對象的某個屬性時,會觸發(fā)該對象里面的setter。如果你對這塊不是很了解,可以先學一下 Object.defineProperty ,包括這兩年超級火的vuejs也是通過這個接口實現(xiàn)的。它是一個ES5的標準接口。
我們可以設計一種實現(xiàn),當你修改或賦值$scope的某個屬性時,就觸發(fā)了$scope這個js對象的setter,我們可以自定義這個setter,在setter函數(shù)內(nèi)部,調(diào)用某些邏輯去更新界面。同時,為了確保新塞進來的對象也可以被監(jiān)聽到變化,在你賦值時,還要把賦值進來的對象也進行改造,改造為可以被監(jiān)聽的對象。
雙向綁定顧名思義是兩個過程,一個是將$scope屬性值綁定到HTML結構中,當$scope屬性值發(fā)生變化的時候界面也發(fā)生變化;另一個是,當用戶在界面上進行操作,例如點擊、輸入、選擇時,自動觸發(fā)$scope屬性的變化(界面也可能跟著變)。而臟檢查的作用是“在當$scope屬性值發(fā)生變化的時候促使界面發(fā)生變化”。
angular的數(shù)據(jù)響應機制
那么,在代碼層面,angular是怎么做到監(jiān)聽數(shù)據(jù)變動然后更新界面的呢?答案是,angular根本不監(jiān)聽數(shù)據(jù)的變動,而是在恰當?shù)臅r機從$rootScope開始遍歷所有$scope,檢查它們上面的屬性值是否有變化,如果有變化,就用一個變量dirty記錄為true,再次進行遍歷,如此往復,直到某一個遍歷完成時,這些$scope的屬性值都沒有變化時,結束遍歷。由于使用了一個dirty變量作為記錄,因此被稱為臟檢查機制。
這里面有三個問題:
要解決這三個問題,我們需要深入了解angular的$watch, $apply, $digest。
$watch綁定要檢查的值
簡單的說,當一個作用域創(chuàng)建的時候,angular會去解析模板中當前作用域下的模板結構,并且自動將那些插值(如{{text}})或調(diào)用(如ng-click="update")找出來,并利用$watch建立綁定,它的回調(diào)函數(shù)用于決定如果新值和舊值不同時(或相同時)要干什么事。當然,你也可以手動在腳本里面使用$scope.$watch對某個屬性進行綁定。它的使用方法如下:
$scope.$watch(string|function, listener, objectEquality, prettyPrintExpression)
新聞熱點
疑難解答
圖片精選