首頁 > web前端 > js教程 > 主體

淺談angular.js中實作雙向綁定的方法$watch $digest $apply_AngularJS

WBOY
發布: 2016-05-16 15:36:40
原創
1135 人瀏覽過

Angular.js 中的特性,雙向綁定.

多麼神奇的功能,讓視圖的改變直接反應到數據中,數據的改變又實時的通知到視圖,如何做到的?

這要歸功於 scope 以下3個重要的方法:

$watch
$digest
$apply

他們的差別是什麼,我們來介紹下:

$watch
這是一個監聽 scope 上資料的監聽器

方法說明:

$scope.$watch('参数',function(newValue,oldValue){
 //逻辑处理
})
登入後複製

上面我們就是創建了一個監聽器.
‘參數' 就是$scope物件下的一個物件(或一個物件的屬性),注意,這裡是字串形式.

假如你要監聽 $scope.name 屬性.

$scope.$watch('name',function(newValue,oldValue){
 //逻辑处理
})
登入後複製

如上代碼, ‘name' 需要引號

參數後面跟著回呼函數,回呼函數參數回傳了被監聽 屬性,變化後的新值,以前變化前的舊值.

$digest

他負責檢查 scope 中的資料是否發生了變化,如果某個屬性有變化,馬上會通知此屬性的監聽器 ($watch 註冊的監聽器),觸發監聽器,執行回調函數.

$apply

這個方法和 $digest 很相似, $digest 檢查scope 中的所有資料
$apply 相當於檢查 rootScope 中的所有資料,他會從父級到子級來檢查所有資料

$apply() == $rootScope.$digest()

$apply() 方法有兩種形式.

第一種 接受一個 function作為參數.
這樣觸發 $digest 函數並且執行一次 參數中的 function

第二種  不接受任何參數.
這樣只是觸發一輪 $digest 父級到子級的循環

Angular.js 中一班不會直接呼叫 $digest ,而是用 $scope.$apply() 來取代

我沒有設定監視器,為什麼視圖和資料可以雙向綁定

例如一個文字方塊 ng-model="name"
這時其實 $scope 物件下已經有了一個屬性 name 來對應和 上面的視圖進行雙向綁定

如何實現的?

其實,當我們定義 ng-model="name"  或 ng-bind="name" 或 {{name}}
這時 angular.js 會在 $scope 模型上自動為 “name” 屬性設定一個監聽器:

$scope.$watch('name', function(newValue, oldValue) {
  //监听 name 属性的变化
});
登入後複製

原來這裡 angular.js 幫我們自動建立了一個監聽器,所以此屬性和 $scope.name 資料才會即時的雙向綁定.

當然,有時候你也會發現明明資料變化了.但是UI 沒有刷新,是雙向綁定失效了嗎?

沒有

只是在 $scope 模型遍歷 digest 循環時,你的資料還沒回,

例如非同步呼叫方法,callbac 傳回的資料
例如你在 setTimeout 設定了定時觸發函數,然後修改模型資料
總之,是錯過了 $scope 模型的 digest 循環,導致模型沒有通知UI去根據新數據刷新.

遇到這樣的問題怎麼辦?

我們只好自己去手動呼叫 digest來循環檢查一次資料.實現雙向綁定

上面我們已經說過,通常不要去直接調用 digest 方法,而是手動調用 $apply 方法,間接實現觸發 $digest 循環.

如下:

setTimeout(function() {
 $scope.name= '一介布衣';
 $scope.$apply();
}, 2000);
登入後複製

問題來了,上面時候該去手動調用 apply 方法

目前為止, angular.js 為一部分指令和服務自動實作了 $apply() 方法.

例如, ng-click ,ng-model ,$timeout服務,$http服務 等

呼叫後,angular.js 會自動幫我們呼叫 $apply() 來實作資料雙向綁定.

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!