筆者AngularJS接觸時間差很少是兩年多,雖然這兩年多AngularJS版本突飛猛進,可是筆者的版本是比較老的1.4.3,一方面是本身對這個版本比較熟悉,另外一方面是老項目須要維護,固然本文筆者也儘量地寫到通俗易懂,畢竟AngularJS在不少設計上也有獨到之處,可是人無完人,筆者可能有疏漏的話,煩請提醒留言。下面迴歸正文,整體而言,AngularJS在設計上有兩點比較重要的地方,分別是指令(directive)和做用域(scope)。directive實現了對經常使用DOM操做的簡要封裝,而渲染的數據源於scope,而這中間的媒介(或者說是反應的容器、載體)是controller,三者相互做用造成AngularJS的基礎設計模式。MVVM框架下就須要雙向綁定,而雙向綁定的實現是基於髒值檢測的digest loop,這也是AngularJS設計比較先進的地方(固然也有缺陷,這個後續再講)。git
本文入門門檻比較高,若對AngularJS剛接觸的同窗請先看一下官方教程,第一講重點講scope,後續講指令。angularjs
AngularJS數據交互示意圖:github
一般來講AngularJS經過scope來抽象化地實現directive和DOM之間的交流,而scope存在controller上的,所以AngularJS不會過多幹涉原生的東西,而是拓展一些新的帶$前綴的內部功能屬性,好比以一個$符號的前綴,以兩個$($$)符號做爲前綴的是AngularJS的私有屬性,通常不推薦使用。設計模式
在AngularJS中,一個scope(做用域)必須與標籤元素關聯,而標籤元素卻不必定跟scope關聯,它們之間不是充要條件,元素能夠經過如下三種方式被指定到一個scope上。數組
- 經過controller或者directive,scope會被指定在一個標籤元素上
- 若標籤元素上沒有指定,則繼承於父標籤上的scope
- 反之,則不指定爲任何一個scope
第一和第二種狀況若接觸過AngularJS,則不難理解,第三種狀況屬於超出AngularJS的執行範圍即在ng-app指令範圍以外。app
digest循環是數據雙向綁定的關鍵,也是AngularJS設計上的關鍵。AngularJS是基於數據綁定特徵,經過一個髒值檢測循環去追蹤數據變化和事件變化,而數據綁定在scope上的,所以scope上確定有觸發這一檢測的方法,而這個就是scope.$digest方法,相應的狀態表現爲$$phase。框架
- $digest-觸發digest循環
- $$phase-digest循環執行狀態{null, '$apply', '$digest'}
講這一過程的以前咱們先介紹watcher(監聽器)及相關屬性函數
- $watch(watchExp, listener,objectEquality)-增長scope監聽器
- $watchCollection-監聽數據對象或者數組
- $$watchers-保持監聽器與scope的關聯
數據雙向綁定的基礎就是$wathch,而數據及時的更新變化卻要依賴於$digest循環,當你每次使用ng-bind,ng-model時都會自動建立一個$watch,所以每當數據變化時都會及時更新到界面上,那麼問題來了,這個及時的背後依靠的是什麼呢?又是何時觸發$digest呢?oop
digest在AngularJS設計上處於核心的位置,要麼被直接觸發,要麼手動調用$apply觸發,而思路上就是service、directive致使直接或者間接地觸發了digest,而digest觸發了scope上的watcher,watcher更新界面數據,這是設計上最基本的思路。設計
而這個間接指的是有些AngularJS封裝過的函數,好比$timeout服務內置$apply方法。而這個直接是指ngModel或者ngBind值上的變動直接致使watcher觸發digest。