這裏是修真院前端小課堂,每篇分享文從html
【背景介紹】【知識剖析】【常見問題】【解決方案】【編碼實戰】【擴展思考】【更多討論】【參考文獻】前端
八個方面深度解析前端知識/技能,本篇分享的是:程序員
【$state、$watch、$scope、$rootScope分別是什麼?】angularjs
angular之中,$state$watch$scope$rootScope分別是什麼?
分享人:聶義中
目錄ajax
1.背景介紹數組
2.知識剖析瀏覽器
3.常見問題app
4.解決方案模塊化
5.編碼實戰函數
6.擴展思考
7.參考文獻
8.更多討論
1.背景介紹
在平時的編碼中,咱們總會想着有什麼方法可以簡化咱們的工做流程,讓咱們只專心於業務邏輯和數據的處理,而angularjs
就爲咱們程序員實現了這一點。AngularJS有着諸多特性,最爲核心的是:MVC、模塊化、自動化雙向數據綁定、語義化標籤、依賴注入等等。下面,咱們將要討論的就是angularJS裏面的$scope$rootScope$watch和$state
2.知識剖析
做用域
咱們能夠把angularJs裏面的做用域看作爲一個容器,在控制器中咱們能夠訪問這個容器咱們能夠往這個容器中放入一些模型數據,在視圖中咱們能夠經過表達式將數據展現給用戶。做用域是應用在HTML(視圖)和JavaScript(控制器)之間的紐帶,他是一個對象,有可用的方法和屬性,可應用在視圖和控制器上。
$rootScope與$scope
【1】當angularJS遇到ng-app指令的時候就會自動生成一個名爲$rootScope的做用域,該做用域就是就是angularJS的根做用域。$rootScope就至關於一個全局做用域,因此咱們保存在其中的東西是全局性的,在任一controller之中都可以使用
【2】當angularJS遇到controller或者一些自定義指令的時候也會自動的生成一個名爲$scope的做用域scope是html和單個controller之間的橋樑,數據綁定就靠他了。
【3】$scope都是$rootScope的子做用域。
$watch
相信使用過angularjs的同窗都知道,ng中有個比較重要的特色,叫作雙向綁定,那麼這個雙向綁定是如何實現的呢?當咱們在對綁定的name屬性進行修改的時候,angular內部的$digest循環級會執行一次,他執行的內容是檢查咱們的$scope做用域的內容與上次執行$digest循環的時候是否有變化,如有變化就執行$watch()方法綁定的處理函數。從而達到了監聽做用域屬性的效果。
$watch(watchExpression,listener,objectEquality);
watchExpression,須要監控的表達式
listener,處理函數,函數參數以下function(newValue,oldValue,scope)
objectEquality,是否深度監聽,若是設置爲true,它告訴Angular檢查所監控的對象中每個屬性的變化.若是你但願監控數組的個別元素或者對象的屬性而不是一個普通的值,那麼你應該使用它
$state
在ajax技術發展普及以後,由於其不會留下歷史記錄方便瀏覽器訪問和對於seo不友好的特色,一個新技術應運而生:路由,$state就是路由中的一項服務。
$state.go()
$state.go()方法能夠產生與a連接同樣的效果,能夠將此方法綁定給一個button按鈕,而後在按鈕的點擊事件中國執行$state.go(),就能夠跳轉到相應的頁面。
$stateParams狀態參數在上面說起使用$stateparams來提取在url中的不一樣參數。該服務的做用是處理url的不一樣部分。例如,當上述的inbox狀態是這樣時:url:'/inbox/:inboxId/messages/{sorted}?from&to'//當用戶訪問者連接時:'/inbox/123/messages/ascending?from=10&to=20'
$stateParams對象的值爲:{inboxId:'123',sorted:'ascending',from:10,to:20}
詳細講解
3.常見問題
watch的深度監聽是什麼意思呢?有什麼優缺點呢?
4.解決方案
$watch在對待原始類型和引用類型會有不一樣的處理方式,這就要首先說一說$watch函數的第三個參數。在前面的例子中,咱們知道,$watch函數有接收兩個參數,第一個參數是須要監視的對象,第二個參數是在監視對象發生變化時須要調用的函數,實際上$watch還有第三個參數,它在默認狀況下是false。在默認狀況下,即不顯式指明第三個參數或者將其指明爲false時,咱們進行的監視叫作「引用監視」。引用監視的原詞的「referencewatch」,它的意思是隻要監視的對象引用沒有發生變化,就不算它發生了變化。具體來講,在上面的例子中,只要是items的引用沒有發生變化,就算items中的一些屬性發生了變化,$watch也會當作沒有看見。
若是咱們將$watch的第三個變量設置爲true,那麼此時咱們進行的監視叫作「全等監視」,原詞是「equalitywatch」。此時,只要$watch的對象有一點風吹草動,它立刻就跳出來
既然全等監視這麼好,那麼咱們爲何不直接用全等監視呢?固然,任何事情都有好的壞的兩個方面,全等監視當然是好,可是它在運行時須要先遍歷整個監視對象,而後在每次$digest以前使用angular.copy()將整個對象深拷貝一遍而後在運行以後用angular.equal()將先後的對象進行對比,上面的例子中由於items比較簡單,所以可能性能上不會有什麼差異,可是到了實際生產時,咱們要面對的數據千千萬萬,可能由於全等監視這一個設置就會消耗大量的資源,讓應用停滯不前
5.編碼實戰
6.擴展思考
7.參考文獻
參考一:深度理解scope
參考二:原始數據類型和對象類型的區別及深度拷貝解析
8.更多討論
1 做用域的繼承方式是什麼?
答: angular裏面的做用域是經過原型鏈的方式來實現繼承的。
2 $watch髒檢測原理
答: scope經過$watch方法向this.
watchers數組中添加watcher對象(包含watchFn,listenerFn,valueEq,last四個屬性)。每當$digest循環被觸發時,它會遍歷
watchers數組中添加watcher對象(包含watchFn,listenerFn,valueEq,last四個屬性)。每當$digest循環被觸發時,它會遍歷
watchers數組,執行watcher中的watchFn,獲取當前scope上某屬性的值(一個watcher對應scope上一個被監聽屬性),而後去同watcher中的last(上一次的值)作比較,若兩值不相等,就執行listenerFn。
3 怎麼定義或修改$rootScope做用域的屬性和方法
答: 能夠將 $rootScope 注入到任何一個控制器的function()裏面,而後在該方法裏面就能夠定義$rootScope的屬性和方法。