淺談angular.js中實現(xiàn)雙向綁定的方法$watch $digest $apply
Angular.js 中的特性,雙向綁定.
多么神奇的功能,讓視圖的改變直接反應(yīng)到數(shù)據(jù)中,數(shù)據(jù)的改變又實時的通知到視圖,如何做到的?
這要歸功于 scope 下面3個重要的方法:
$watch
$digest
$apply
他們的區(qū)別是什么,我們來介紹下:
$watch
這是一個監(jiān)聽 scope 上數(shù)據(jù)的監(jiān)聽器
方法說明:
$scope.$watch('參數(shù)',function(newValue,oldValue){
//邏輯處理
})
上面我們就是創(chuàng)建了一個監(jiān)聽器.
‘參數(shù)' 就是$scope對象下的一個對象(或者一個對象的屬性),注意,這里是字符串形式.
假如你要監(jiān)聽 $scope.name 屬性.
$scope.$watch('name',function(newValue,oldValue){
//邏輯處理
})
如上代碼, ‘name' 需要引號
參數(shù)后面跟著回調(diào)函數(shù),回調(diào)函數(shù)參數(shù)返回了被監(jiān)聽 屬性,變化后的新值,以前變化前的舊值.
$digest
他負責(zé)檢查 scope 中的數(shù)據(jù)是否發(fā)生了變化,如果某個屬性有變化,馬上會通知此屬性的監(jiān)聽器 ($watch 注冊的監(jiān)聽器),觸發(fā)監(jiān)聽器,執(zhí)行回調(diào)函數(shù).
$apply
這個方法和 $digest 很相似, $digest 檢查scope 中的所有數(shù)據(jù)
$apply 相當(dāng)于檢查 rootScope 中的所有數(shù)據(jù),他會從父級到子級來檢查所有數(shù)據(jù)
$apply() == $rootScope.$digest()
$apply() 方法有兩種形式.
第一種 接受一個 function作為參數(shù).
這樣觸發(fā) $digest 函數(shù)并且執(zhí)行一次 參數(shù)中的 function
第二種 不接受任何參數(shù).
這樣只是觸發(fā)一輪 $digest 父級到子級的循環(huán)
Angular.js 中一班不會直接調(diào)用 $digest ,而是用 $scope.$apply() 來代替
我沒有設(shè)定監(jiān)視器,為什么視圖和數(shù)據(jù)可以雙向綁定
比如一個文本框 ng-model="name"
這時其實 $scope 對象下已經(jīng)有了一個屬性 name 來對應(yīng)和 上面的視圖進行雙向綁定
如何實現(xiàn)的?
其實,當(dāng)我們定義 ng-model="name" 或者 ng-bind="name" 或者 {{name}}
這時 angular.js 會在 $scope 模型上自動為 “name” 屬性設(shè)置一個監(jiān)聽器:
$scope.$watch('name', function(newValue, oldValue) {
//監(jiān)聽 name 屬性的變化
});
原來這里 angular.js 幫我們自動創(chuàng)建了一個監(jiān)聽器,所以此屬性和 $scope.name 數(shù)據(jù)才會實時的雙向綁定.
當(dāng)然,有時候你也會發(fā)現(xiàn)明明數(shù)據(jù)變化了.但是UI 沒有刷新,是雙向綁定失效了嗎?
沒有
只是在 $scope 模型遍歷 digest 循環(huán)時,你的數(shù)據(jù)還沒有返回來,
比如異步調(diào)用方法,callbac 返回的數(shù)據(jù)
比如你在 setTimeout 設(shè)置了定時觸發(fā)函數(shù),然后修改模型數(shù)據(jù)
總之,是錯過了 $scope 模型的 digest 循環(huán),導(dǎo)致模型沒有通知UI去根據(jù)新數(shù)據(jù)刷新.
遇到這樣的問題怎么辦?
我們只好自己去手動調(diào)用 digest來循環(huán)檢查一次數(shù)據(jù).實現(xiàn)雙向綁定
上面我們已經(jīng)說過,通常不要去直接調(diào)用 digest 方法,而是手動調(diào)用 $apply 方法,間接實現(xiàn)觸發(fā) $digest 循環(huán).
如下:
setTimeout(function() {
$scope.name= '一介布衣';
$scope.$apply();
}, 2000);
問題來了,上面時候該去手動調(diào)用 apply 方法
目前為止, angular.js 為一部分指令和服務(wù)自動實現(xiàn)了 $apply() 方法.
例如, ng-click ,ng-model ,$timeout服務(wù),$http服務(wù) 等
調(diào)用后,angular.js 會自動幫我們調(diào)用 $apply() 來實現(xiàn)數(shù)據(jù)雙向綁定.
- angularJS中$apply()方法詳解
- AngularJS中的$watch(),$digest()和$apply()區(qū)分
- 全面解析Angular中$Apply()及$Digest()的區(qū)別
- AngularJS中$apply方法和$watch方法用法總結(jié)
- AngularJS報錯$apply already in progress的解決方法分析
- Angular項目中$scope.$apply()方法的使用詳解
- angularjs 中$apply,$digest,$watch詳解
- Angular.js中$apply()和$digest()的深入理解
- AngularJS雙向數(shù)據(jù)綁定原理之$watch、$apply和$digest的應(yīng)用
- Angularjs中的$apply及優(yōu)化使用詳解
相關(guān)文章
Angular動態(tài)綁定樣式及改變UI框架樣式的方法小結(jié)
AngularJS 是一個 JavaScript 框架。它是一個以 JavaScript 編寫的庫。這篇文章主要介紹了Angular動態(tài)綁定樣式及改變UI框架樣式的方法小結(jié),需要的朋友可以參考下2018-09-09
Angular Excel 導(dǎo)入與導(dǎo)出的實現(xiàn)代碼
這篇文章主要介紹了Angular Excel 導(dǎo)入與導(dǎo)出的實現(xiàn)代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-04-04
Angular依賴注入optional?constructor?parameters概念
這篇文章主要為大家介紹了Angular?依賴注入領(lǐng)域里?optional?constructor?parameters?的概念及使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-11-11
angularJs自定義過濾器實現(xiàn)手機號信息隱藏的方法
今天小編就為大家分享一篇angularJs自定義過濾器實現(xiàn)手機號信息隱藏的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-10-10
Angular引入swiper后autoplay失效的解決辦法詳解
這篇文章主要介紹了Angular引入swiper后autoplay失效的解決辦法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09

