淺談angular.js中實(shí)現(xiàn)雙向綁定的方法$watch $digest $apply
Angular.js 中的特性,雙向綁定.
多么神奇的功能,讓視圖的改變直接反應(yīng)到數(shù)據(jù)中,數(shù)據(jù)的改變又實(shí)時(shí)的通知到視圖,如何做到的?
這要?dú)w功于 scope 下面3個(gè)重要的方法:
$watch
$digest
$apply
他們的區(qū)別是什么,我們來(lái)介紹下:
$watch
這是一個(gè)監(jiān)聽(tīng) scope 上數(shù)據(jù)的監(jiān)聽(tīng)器
方法說(shuō)明:
$scope.$watch('參數(shù)',function(newValue,oldValue){ //邏輯處理 })
上面我們就是創(chuàng)建了一個(gè)監(jiān)聽(tīng)器.
‘參數(shù)' 就是$scope對(duì)象下的一個(gè)對(duì)象(或者一個(gè)對(duì)象的屬性),注意,這里是字符串形式.
假如你要監(jiān)聽(tīng) $scope.name 屬性.
$scope.$watch('name',function(newValue,oldValue){ //邏輯處理 })
如上代碼, ‘name' 需要引號(hào)
參數(shù)后面跟著回調(diào)函數(shù),回調(diào)函數(shù)參數(shù)返回了被監(jiān)聽(tīng) 屬性,變化后的新值,以前變化前的舊值.
$digest
他負(fù)責(zé)檢查 scope 中的數(shù)據(jù)是否發(fā)生了變化,如果某個(gè)屬性有變化,馬上會(huì)通知此屬性的監(jiān)聽(tīng)器 ($watch 注冊(cè)的監(jiān)聽(tīng)器),觸發(fā)監(jiān)聽(tīng)器,執(zhí)行回調(diào)函數(shù).
$apply
這個(gè)方法和 $digest 很相似, $digest 檢查scope 中的所有數(shù)據(jù)
$apply 相當(dāng)于檢查 rootScope 中的所有數(shù)據(jù),他會(huì)從父級(jí)到子級(jí)來(lái)檢查所有數(shù)據(jù)
$apply() == $rootScope.$digest()
$apply() 方法有兩種形式.
第一種 接受一個(gè) function作為參數(shù).
這樣觸發(fā) $digest 函數(shù)并且執(zhí)行一次 參數(shù)中的 function
第二種 不接受任何參數(shù).
這樣只是觸發(fā)一輪 $digest 父級(jí)到子級(jí)的循環(huán)
Angular.js 中一班不會(huì)直接調(diào)用 $digest ,而是用 $scope.$apply() 來(lái)代替
我沒(méi)有設(shè)定監(jiān)視器,為什么視圖和數(shù)據(jù)可以雙向綁定
比如一個(gè)文本框 ng-model="name"
這時(shí)其實(shí) $scope 對(duì)象下已經(jīng)有了一個(gè)屬性 name 來(lái)對(duì)應(yīng)和 上面的視圖進(jìn)行雙向綁定
如何實(shí)現(xiàn)的?
其實(shí),當(dāng)我們定義 ng-model="name" 或者 ng-bind="name" 或者 {{name}}
這時(shí) angular.js 會(huì)在 $scope 模型上自動(dòng)為 “name” 屬性設(shè)置一個(gè)監(jiān)聽(tīng)器:
$scope.$watch('name', function(newValue, oldValue) { //監(jiān)聽(tīng) name 屬性的變化 });
原來(lái)這里 angular.js 幫我們自動(dòng)創(chuàng)建了一個(gè)監(jiān)聽(tīng)器,所以此屬性和 $scope.name 數(shù)據(jù)才會(huì)實(shí)時(shí)的雙向綁定.
當(dāng)然,有時(shí)候你也會(huì)發(fā)現(xiàn)明明數(shù)據(jù)變化了.但是UI 沒(méi)有刷新,是雙向綁定失效了嗎?
沒(méi)有
只是在 $scope 模型遍歷 digest 循環(huán)時(shí),你的數(shù)據(jù)還沒(méi)有返回來(lái),
比如異步調(diào)用方法,callbac 返回的數(shù)據(jù)
比如你在 setTimeout 設(shè)置了定時(shí)觸發(fā)函數(shù),然后修改模型數(shù)據(jù)
總之,是錯(cuò)過(guò)了 $scope 模型的 digest 循環(huán),導(dǎo)致模型沒(méi)有通知UI去根據(jù)新數(shù)據(jù)刷新.
遇到這樣的問(wèn)題怎么辦?
我們只好自己去手動(dòng)調(diào)用 digest來(lái)循環(huán)檢查一次數(shù)據(jù).實(shí)現(xiàn)雙向綁定
上面我們已經(jīng)說(shuō)過(guò),通常不要去直接調(diào)用 digest 方法,而是手動(dòng)調(diào)用 $apply 方法,間接實(shí)現(xiàn)觸發(fā) $digest 循環(huán).
如下:
setTimeout(function() { $scope.name= '一介布衣'; $scope.$apply(); }, 2000);
問(wèn)題來(lái)了,上面時(shí)候該去手動(dòng)調(diào)用 apply 方法
目前為止, angular.js 為一部分指令和服務(wù)自動(dòng)實(shí)現(xiàn)了 $apply() 方法.
例如, ng-click ,ng-model ,$timeout服務(wù),$http服務(wù) 等
調(diào)用后,angular.js 會(huì)自動(dòng)幫我們調(diào)用 $apply() 來(lái)實(shí)現(xiàn)數(shù)據(jù)雙向綁定.
- angularJS中$apply()方法詳解
- AngularJS中的$watch(),$digest()和$apply()區(qū)分
- 全面解析Angular中$Apply()及$Digest()的區(qū)別
- AngularJS中$apply方法和$watch方法用法總結(jié)
- AngularJS報(bào)錯(cuò)$apply already in progress的解決方法分析
- Angular項(xiàng)目中$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實(shí)現(xiàn)表格自滾動(dòng)效果
這篇文章主要為大家介紹了如何通過(guò)Angular實(shí)現(xiàn)表格自動(dòng)滾動(dòng)的效果,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Angular有一定幫助,需要的可以參考一下2022-01-01Angular.js中下拉框?qū)崿F(xiàn)渲染html的方法
這篇文章主要給大家介紹了關(guān)于在Angular.js中下拉框?qū)崿F(xiàn)渲染html的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)跟著小編一起來(lái)學(xué)習(xí)學(xué)習(xí)吧。2017-06-06Angular2.0實(shí)現(xiàn)modal對(duì)話框的方法示例
這篇文章主要介紹了Angular2.0實(shí)現(xiàn)modal對(duì)話框的方法,結(jié)合實(shí)例形式分析了angular2.0實(shí)現(xiàn)modal對(duì)話框的樣式、界面及功能等相關(guān)操作技巧,需要的朋友可以參考下2018-02-02angular中兩種表單的區(qū)別(響應(yīng)式和模板驅(qū)動(dòng)表單)
這篇文章主要介紹了angular中兩種表單的區(qū)別(響應(yīng)式和模板驅(qū)動(dòng)表單),詳細(xì)的介紹了這兩種表單的實(shí)現(xiàn)以及區(qū)別,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-12-12詳解關(guān)于Angular4 ng-zorro使用過(guò)程中遇到的問(wèn)題
這篇文章主要介紹了詳解關(guān)于Angular4 ng-zorro使用過(guò)程中遇到的問(wèn)題,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12Angularjs編寫KindEditor,UEidtor,jQuery指令
使用過(guò) AngularJS 的朋友應(yīng)該最感興趣的是它的指令?,F(xiàn)今市場(chǎng)上的前端框架也只有AngularJS 擁有自定義指令的功能,并且AngularJS 是目前唯一提供Web應(yīng)用可復(fù)用能力的框架。2015-01-01angularjs實(shí)現(xiàn)的購(gòu)物金額計(jì)算工具示例
這篇文章主要介紹了angularjs實(shí)現(xiàn)的購(gòu)物金額計(jì)算工具,涉及AngularJS事件監(jiān)聽(tīng)、數(shù)值計(jì)算相關(guān)操作技巧,需要的朋友可以參考下2018-05-05angularjs實(shí)現(xiàn)首頁(yè)輪播圖效果
這篇文章主要為大家詳細(xì)介紹了angularjs實(shí)現(xiàn)首頁(yè)輪播圖效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04