JS學習筆記——AngularJS 1.x雙向資料繫結機制
阿新 • • 發佈:2019-01-02
0.前言
AngularJS和vueJS是前端比較熱門的兩個框架,AngularJS 1.x是我第一個接觸的框架,雙向繫結是其最大的特點,我們從原生JS的角度看看,這個雙向資料繫結是如何實現的。點這裡看vueJS的雙向繫結原理。
1.簡單的雙向繫結實現
AngularJS的雙向繫結基於髒檢測(dirty checking)
。所謂的dirty checking就是對比新舊兩個值,如果有變化(形象點說,就是這個值髒了),就更新。AngularJS註冊了以下幾個事件,當這些事件發生後,就會開始”髒檢測”。”髒檢測”的核心函式是$digest()
。
- DOM事件(Click, Keyup)
- XHR響應
- 瀏覽器Location變化
- Timer事件(
setTimeout()
和setInterval()
) - 手動執行
$digest()
或$apply()
model->view:$scope
下的變量出現變化,執行DOM更新。
view->model:監聽DOM事件,在事件處理程式中改變$scope下的變數。
下面以AngularJS中的ng-click
和ng-bind
兩個指令為例子,說說如何實現雙向繫結。
<div>
<form>
<input type="text" ng-bind="count" />
<button type="button" ng-click="increment" >increment</button>
</form>
<div ng-bind="count">
</div>
</div>
//建構函式
function Scope(){
this.$$watchers = [];//需要繫結的變數列表
}
Scope.prototype.$watch = function(){
//往$$watchers裡面加需要繫結的變數
}
Scope.prototype.$digest = function (){
//髒檢測
//迴圈檢測$$watchers裡的所有資料,對比是否變化:如果沒有變化,再迴圈一次確認是否變化,直到連續兩次不變(最多迴圈10次);如果發生變化,則更新DOM
}
window.load = function(){
var $scope = new Scope();
for(var key in $scope) {
//把$scope中的變數新增到$$watchers列表中
}
//處理帶有ng-click和ng-bind指令的元素
//V->M:給這兩個元素繫結事件處理程式,在程式中修改model
//M->V:因為修改了model,然後馬上呼叫$scope.$digest()
}
由於$digest需要迴圈檢測繫結的變數,因此AngularJS推薦一個頁面繫結的view最好不要超過2000個。