大家好,我是IT修真院深圳分院第3期的學(xué)員芝加,一枚正直純潔善良的前端程序員茫打,今天給大家分享一下,修真院官網(wǎng)前端工程師【JS-10】深度思考中的知識點(diǎn)——ngularjs雙向綁定后,發(fā)生了什么事情老赤?是什么可以讓view層和Controller層進(jìn)行綁定的轮洋??
1.背景介紹
介紹雙向綁定之前,我們先介紹一下單向綁定抬旺。
單向數(shù)據(jù)綁定:指的是我們先把模板寫好弊予,然后把模板和數(shù)據(jù)(數(shù)據(jù)可能來自后臺)整合到一起形成HTML代碼,然后把這段HTML代碼插入到文檔流里面,但是單向綁定有個缺點(diǎn)开财,就是如果有新的數(shù)據(jù)來了汉柒,那就必須把之前的HTML代碼去掉,再重新把新的數(shù)據(jù)和模板一起整合后插入到文檔流中责鳍。
雙向綁定:數(shù)據(jù)模型和視圖之間的雙向綁定碾褂。意思就是當(dāng)用戶在視圖上的修改會自動同步到數(shù)據(jù)中去,同樣的历葛,如果數(shù)據(jù)中的值發(fā)生了變化正塌,也會立刻同步到視圖中去。
AngularJS模板的工作原理不同恤溶。不同之處在于:第一乓诽,模板(附加了自定義屬性等標(biāo)記的未經(jīng)編譯的HTML)是由瀏覽器編譯的;
第二咒程,編譯最后產(chǎn)生的是一個動態(tài)的視圖鸠天。這里動態(tài)指的是視圖的任何變化都會直接反應(yīng)到模型,反之亦然帐姻。這使得模型總是應(yīng)用狀態(tài)的唯一標(biāo)識稠集,這大大簡化了開發(fā)人員的編程工作。你可以簡單地認(rèn)為視圖只是模型的投影饥瓷。
2.知識剖析
angularjs雙向綁定后剥纷,發(fā)生了什么事情?
什么讓view層和Controller層進(jìn)行綁定的扛伍?
首先我們要知道angularjs是怎么運(yùn)行筷畦,怎么初始化的词裤。
讓我們來看看DOM文檔加載的步驟
1刺洒、解析HTML結(jié)構(gòu)。
2吼砂、加載外部腳本和樣式表文件逆航。
3、解析并執(zhí)行腳本代碼渔肩。
4因俐、DOM樹構(gòu)建完成槐瑞。//DOMContentLoaded
5邑滨、加載圖片等外部文件。
6、頁面加載完畢慌植。//load
AngularJS會在DOMContentLoaded事件觸發(fā)時執(zhí)行,并通過ng-app指令 尋找你的應(yīng)用根作用域习柠。如果ng-app指令找到了疏魏,那么AngularJS將會:
載入和 指令 內(nèi)容相關(guān)的模塊。
創(chuàng)建一個應(yīng)用的“注入器(injector)”钳踊。
已擁有ng-app指令 的標(biāo)簽為根節(jié)點(diǎn)來編譯其中的DOM衷敌。這使得你可以只指定DOM中的一部分作為你的AngularJS應(yīng)用。
這個時候我們有了一個根作用域$rootscope
讓我們回顧一下MVVM
MVVM拓瞪,雖然它的名稱里沒有C缴罗,但并不表示它就沒有Controller。相反祭埂,由于MVVM里的Controller和View聯(lián)系緊密面氓,已經(jīng)融為一體了。所以沟堡,可以把MVVM理解為MVCVM侧但,或者把MVVM里的V理解為VC,即View和Controller航罗。
MVVM里的VM指的是ViewModel禀横,它把MVC中原本屬于Controller的業(yè)務(wù)邏輯部分抽離出來形成了ViewModel。這樣粥血,Controller里只剩下和View交互相關(guān)的部分柏锄,而業(yè)務(wù)邏輯這種與視圖顯示、視圖交互無關(guān)的部分則獨(dú)立為ViewModel复亏。
所以趾娃,Controller和View結(jié)合到一起,和ViewModel互相交流缔御,而ViewModel再和Model交流抬闷。
現(xiàn)在讓我們看看$scope在雙向數(shù)據(jù)綁定中起的左右
在表面上我們已經(jīng)知道angularjs是怎么進(jìn)行數(shù)據(jù)綁定的,接著在改變數(shù)據(jù)的時候耕突,到底發(fā)生了什么使得數(shù)據(jù)可以雙向綁定呢笤成?
答案就是
“臟值檢查”
當(dāng)使用ng-model時,可以使用雙向數(shù)據(jù)綁定
AngularJS使用$scope.$watch(視圖到模型)以及$scope.$apply(模型到視圖)來實(shí)現(xiàn)這個功能眷茁。
$watch?$apply?是什么鬼東西炕泳?
他們是兩個angualrjs內(nèi)置的函數(shù),
$scope.$watch函數(shù),監(jiān)視一個變量的變化上祈。它指明了”要觀察什么”(watchExp)培遵,”在變化時要發(fā)生什么”(listener),以及你要監(jiān)視的是一個變量還是一個對象
$scope中的$$watchers變量保存著我們定義的所有的監(jiān)視器浙芙。如果你在控制臺中查看$$watchers,你會發(fā)現(xiàn)它是一個對象數(shù)組籽腕。
當(dāng)一個控制器/指令/等等東西在AngularJS中運(yùn)行時嗡呼,AngularJS內(nèi)部會運(yùn)行一個叫做$scope.$apply的函數(shù)。
這個$apply函數(shù)會接收一個函數(shù)作為參數(shù)并運(yùn)行它皇耗,在這之后才會在rootScope上運(yùn)行$digest函數(shù)晤锥。
$digest函數(shù)將會在$rootScope中被$scope.$apply所調(diào)用。它將會在$rootScope中運(yùn)行digest循環(huán)廊宪,然后向下遍歷每一個作用域并在每個作用域上運(yùn)行循環(huán)矾瘾。在簡單的情形中,digest循環(huán)將會觸發(fā)所有位于$$watchers變量中的所有watchExp函數(shù)箭启,將它們和最新的值進(jìn)行對比壕翩,如果值不相同,就會觸發(fā)監(jiān)聽器傅寡。
簡單的說$watch用來監(jiān)聽放妈,$apply用來循環(huán)
上面有說到$digest,它和$apply的不同在于
當(dāng)調(diào)用$digest的時候荐操,只觸發(fā)當(dāng)前作用域和它的子作用域上的監(jiān)控芜抒,但是當(dāng)調(diào)用$apply的時候,會觸發(fā)作用域樹上的所有監(jiān)控托启。
MVC的基本概念
MVC模式的意思是宅倒,軟件可以分成三個部分,angularjs也是基于MVC的概念
視圖(View):用戶界面。
控制器(Controller):業(yè)務(wù)邏輯屯耸。
模型(Model):數(shù)據(jù)保存
使用MVC的目的是將M和V的實(shí)現(xiàn)代碼分離拐迁,從而使同一個程序可以使用不同的表現(xiàn)形式。比如一批統(tǒng)計數(shù)據(jù)可以分別用柱狀圖疗绣、餅圖來表示线召。C存在的目的則是確保M和V的同步,一旦M改變多矮,V應(yīng)該同步更新缓淹。
3.常見問題
angularjs雙向綁定后,發(fā)生了什么事情塔逃?
怎么讓有數(shù)據(jù)和無數(shù)據(jù)的情況下讯壶,顯示的內(nèi)容不一樣?
4.解決方案
當(dāng)你在使用ng-model時,AngularJS使用$scope.$watch(視圖到模型)以及$scope.$apply(模型到視圖)來實(shí)現(xiàn)這個功能患雏。
angularjs的ng-show和ng-hide都接受一個參數(shù)鹏溯,這個參數(shù)是一個表達(dá)式罢维,當(dāng)這個表達(dá)式用true的時候執(zhí)行淹仑,這就相當(dāng)于JS的if和else了丙挽,在angular里只需要一行HTML代碼就可以執(zhí)行,非常的簡單粗暴
5.編碼實(shí)戰(zhàn)
6.拓展思考
今天我們的標(biāo)題是什么可以讓view層和Controller層進(jìn)行綁定,可是在剛剛講的知識剖析里匀借,MVC是model層和view層進(jìn)行綁定颜阐,Controller只是起到一個橋梁的作用。
事實(shí)上吓肋,這是最傳統(tǒng)的MVC結(jié)構(gòu)凳怨。在這種結(jié)構(gòu)下,View和Model互相持有是鬼,甚至View和Controller以及Controller和Model的關(guān)系都是千絲萬縷肤舞,非常不利于維護(hù)。所以均蜜,后來的MVC發(fā)展出了新的結(jié)構(gòu)李剖。
我們來看看新的關(guān)系鏈:
View向Controller傳遞交互信息
Controller通知Model改變數(shù)據(jù)
Model更新數(shù)據(jù)后通知Controller改變數(shù)據(jù)
Controller得知數(shù)據(jù)改變后通知View更新視圖
可以看到,演變出來的新MVC去掉了View和Model之間的聯(lián)系囤耳,讓View只與Controller交流篙顺,而Model也只與Controller交流。而這樣的結(jié)構(gòu)也稱之為重量級視圖控制器結(jié)構(gòu)充择,除了視圖部分和數(shù)據(jù)部分德玫,其余的都交給Controller
這樣可以讓View和Model之間的解耦(獨(dú)立)有利于項(xiàng)目的開發(fā),讓負(fù)責(zé)不同模塊的開發(fā)人員不用擔(dān)心自己的改動影響到別人的代碼
7.參考文獻(xiàn)
參考一:賢心博客
參考二:Angular沉思錄(一)數(shù)據(jù)綁定
參考三:AngularJS數(shù)據(jù)雙向綁定揭秘
參考四:AngularJS開發(fā)指南03:HTML編譯器
參考五:AngularJS開發(fā)指南22:AngularJS中的數(shù)據(jù)綁定
參考六:深入解析AngularJS框架中$scope的作用與生命周期
參考七:說說視圖層架構(gòu)
8.更多討論
問:var vm=this中的this指向什么
答:當(dāng)前作用域$scope
問:如何利用臟檢查實(shí)現(xiàn)雙向數(shù)據(jù)綁定椎麦?
答:$watch監(jiān)控宰僧,$apple循環(huán)、替換观挎。
問:angular 的缺點(diǎn)有哪些撒桨?
答:雙向數(shù)據(jù)綁定
PPT
視頻
如果這篇文章對你有幫助,并且使你對修真院免費(fèi)在線學(xué)習(xí)感興趣键兜,可以通過我的鏈接注冊成員會凤类,這會使我得到學(xué)分(兌換學(xué)時)延長學(xué)習(xí)時間:
邀請鏈接:http://www.jnshu.com/login/1/13374512