ANGULARJS雙向綁定后,發生了什么事情?是什么可以讓VIEW層和CONTROLLER層進行綁定的?

大家好,我是IT修真院成都分院第3期的學員王奎智,一枚正直純潔善良的WEB前端程序員。

今天給大家分享一下,修真院官網JS任務8,ANGULARJS雙向綁定后,發生了什么事情?是什么可以讓VIEW層和CONTROLLER層進行綁定的?

1.背景介紹

Angular實現了雙向綁定機制

所謂的雙向綁定,無非是從界面的操作能實時反映到數據,數據的變更能實時展現到界面

2.如何綁定

如果讓我們自己實現雙向綁定該怎么寫:



3.如何實現

眾所周知,angular是一個MVVM(Model-View,View-Model)模式的框架,可以實現數據和視圖數據綁定。MVVM把數據加工的任務從Controller中解放了出來。使得Controller只需專注于數據調配的工作。

View是angularjs編譯html后呈現出來的,需要編譯的是controller中的定義的屬性和方法以及directive中定義的指令。

View和controller是獨立開來的,他們之間的紐帶就是圖中間的膠水——scope。Controller負責向scope中提供屬性和方法,便于和view層面的html進行交互。


Angular雙向綁定通過watch,digest和apply實現的。

watch序列

watch監控model中是否有變化,會記錄last值,也就是改變后的值,每一個model都會增加一個watch到watch隊列中。

digest循環

當瀏覽器接收到可以被angular context處理的事件時,digest循環就會觸發,這個循環有兩個子循環,一個處理evalAsync隊列,另一個處理watch隊列,digest會遍歷watch,然后詢問:

既然所有的watch都檢查完了,那就要問了:有沒有watch更新過?如果有至少一個更新過,這個循環就會再次觸發,直到所有的watch都沒有變化。這樣就能夠保證每個model都已經不會再變化。記住如果循環超過10次的話,它將會拋出一個異常,防止無限循環。 當digest循環結束時,DOM相應地變化。


這個就是所謂的dirty-check,angular實際會引入了一個初始值為false的dirty變量作為循環條件,如果有改變過(也就是新舊值不相等),dirty變為true,循環繼續。這里很重要的(也是許多人的很蛋疼的地方)是每一個進入angular context的事件都會執行一個digest循環,也就是說每次我們輸入一個字母循環都會檢查整個頁面的所有watch。

那是什么決定一個事件是否進入angular context呢?

答案是apply

我之前碰到過在angular中使用普通的事件,無法雙向綁定的事情:

這里值雖然改變了,但是沒有強制執行$degest,監視foo的watch根本沒有執行,執行一次apply之后,watch就會知道這些變化,更新dom了。


這里只需要加上scope.$apply()就行了。

一般帶ng的事件angular都會給你自動添加好了apply,所以你要操縱事件的時候加上apply才能實現數據輸出到view層中。

4.常見問題

digest和apply有何區別?干嘛不直接使用digest?

5.解決方法

1.apply可以帶參數,它可以接受一個函數,然后在應用數據之后,調用這個函數。

2.當調用digest的時候,只觸發當前作用域和它的子作用域上的監控,但是當調用apply的時候,會觸發作用域樹上的所有監控。

請看這個例子:


6.擴展思考

7.參考文獻

參考一:Angular中文社區

參考二:杰鍋鍋的博客

8.更多討論

問題一:為什么例五里面自定義指令需要調用$apply方法?是不是自定義指令都不具備$apply方法?

答:不是。不是因為自定義指令本身不具有$apply方法,因為element.on(“click”,function{})這實際上是一個jQuery方法,而jQuery是不具備$apply方法的。如果我們把scope.b++使用一個angular方法去觸發,是不用調用$apply就可以觸發的。

問題二:前文提到的循環十次會拋出異常,是指什么?

是指在一個ng-指令(本身已經自帶$apply方法)內部再次調用$apply方法,就會拋出異常。這實際上是angular的保護機制。

問題三:dirty-checking這么復雜,會不會速度很慢?

不會的,實際上運行的很快。而且在ES6普及后,angular的未來版本會加入Object.observe,$digest循環的速度會更快。


ANGULARJS雙向綁定后,發生了什么事情_騰訊視頻

視頻鏈接

PPT鏈接

鳴謝

感謝大家觀看

今天的分享就到這里啦,歡迎大家點贊、轉發、留言、拍磚~

你可以直接點擊此鏈接與我一起學習:修真院

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容