<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        深入探究AngularJS框架中Scope對象的超級教程_AngularJS

        來源:懂視網 責編:小采 時間:2020-11-27 21:48:19
        文檔

        深入探究AngularJS框架中Scope對象的超級教程_AngularJS

        深入探究AngularJS框架中Scope對象的超級教程_AngularJS:一、遇到的問題 問題發生在使用 AngularJS 嵌套 Controller 的時候。因為每個 Controller 都有它對應的 Scope(相當于作用域、控制范圍),所以 Controller 的嵌套,也就意味著 Scope 的嵌套。這個時候如果兩個 Scope 內都有同名的 Model 會發
        推薦度:
        導讀深入探究AngularJS框架中Scope對象的超級教程_AngularJS:一、遇到的問題 問題發生在使用 AngularJS 嵌套 Controller 的時候。因為每個 Controller 都有它對應的 Scope(相當于作用域、控制范圍),所以 Controller 的嵌套,也就意味著 Scope 的嵌套。這個時候如果兩個 Scope 內都有同名的 Model 會發
        一、遇到的問題
        問題發生在使用 AngularJS 嵌套 Controller 的時候。因為每個 Controller 都有它對應的 Scope(相當于作用域、控制范圍),所以 Controller 的嵌套,也就意味著 Scope 的嵌套。這個時候如果兩個 Scope 內都有同名的 Model 會發生什么呢?從子 Scope 怎樣更新父 Scope 里的 Model 呢?

        這個問題很典型,比方說當前頁面是一個產品列表,那么就需要定義一個 ProductListController

        你大概看到了在 Scope 里還定義了一個 selectedProduct 的 Model,表示選中了某一個產品。這時會獲取該產品詳情,而頁面通過 AngularJS 中的 $routeProvider 自動更新,拉取新的詳情頁模板,模板中有一個 ProductDetailController

        有趣的事情發生了,在這里也有一個 selectedProduct ,它會怎樣影響 ProductListController 中的 selectedProduct 呢?

        答案是沒有影響。在 AnuglarJS 里子 Scope 確實會繼承父 Scope 中的對象,但當你試下對基本數據類型(string, number, boolean)的 雙向數據綁定 時,就會發現一些奇怪的行為,繼承并不像你想象的那樣工作。子 Scope 的屬性隱藏(覆蓋)了父 Scope 中的同名屬性,對子 Scope 屬性(表單元素)的更改并不更新父 Scope 屬性的值。這個行為實際上不是 AngularJS 特有的,JavaScript 本身的原型鏈就是這樣工作的。開發者通常都沒有意識到 ng-repeat, ng-switch, ng-view 和 ng-include 統統都創建了他們新的子 scopes,所以在用到這些 directive 時也經常出問題。

        二、解決的辦法
        解決的辦法就是不使用基本數據類型,而在 Model 里永遠多加一個點.

        使用

        來替代

        是不是很坑爹?下面這個例子很明確地表達了我所想表達的奇葩現象

        查看 在線演示 DEMO
        但是我真的確實十分很非常需要使用 string number 等原始數據類型怎么辦呢?2 個方法——

        在子 Scope 中使用 $parent.parentPrimitive。 這將阻止子 Scope 創建它自己的屬性。
        在父 Scope 中定義一個函數,讓子 Scope 調用,傳遞原始數據類型的參數給父親,從而更新父 Scope 中的屬性。(并不總是可行)
        三、JavaScript 的原型鏈繼承
        吐槽完畢,我們來深入了解一下 JavaScript 的原型鏈。這很重要,特別是當你從服務器端開發轉到前端,你應該會很熟悉經典的 Class 類繼承,我們來回顧一下。

        假設父類 parentScope 有如下成員屬性 aString, aNumber, anArray, anObject, 以及 aFunction。子類 childScope 原型繼承父類 parentScope,于是我們有:

        201614150604637.png (619×257)

        如果子 Scope 嘗試去訪問 parentScope 中定義的屬性,JavaScript 會先在子 Scope 中查找,如果沒有該屬性,則找它繼承的 scope 去獲取屬性,如果繼承的原型對象 parentScope 中都沒有該屬性,那么繼續在它的原型中尋找,從原型鏈一直往上直到到達 rootScope。所以,下面的表達式結果都是 ture:

        假設我們執行下面的語句

        原型鏈并沒有被查詢,反而是在 childScope 中增加了一個新屬性 aString。這個新屬性隱藏(覆蓋)了 parentScope 中的同名屬性。在下面我們討論 ng-repeat 和 ng-include 時這個概念很重要。

        201614150634794.png (619×257)

        假設我們執行這個操作:

        原型鏈被查詢了,因為對象 anArray 和 anObject 在 childScope 中沒有找到。它們在 parentScope 中被找到了,并且值被更新。childScope 中沒有增加新的屬性,也沒有任何新的對象被創建。(注:在 JavaScript 中,array 和 function 都是對象)

        201614150658628.png (608×257)

        假設我們執行這個操作:

        原型鏈沒有被查詢,并且子 Scope 新加入了兩個新的對象屬性,它們隱藏(覆蓋)了 parentScope 中的同名對象屬性。

        201614150718718.png (608×320)

        應該可以總結

        如果讀取 childScope.propertyX,并且 childScope 有屬性 propertyX,那么原型鏈沒有被查詢。
        如果設置 childScope.propertyX,原型鏈不會被查詢。
        最后一種情況,

        我們從 childScope 刪除了屬性,則當我們再次訪問該屬性時,原型鏈會被查詢。刪除對象的屬性會讓來自原型鏈中的屬性浮現出來。

        201614150741147.png (608×320)

        四、AngularJS 的 Scope 繼承
        創建新的 Scope,并且原型繼承:ng-repeat, ng-include, ng-switch, ng-view, ng-controller, directive with scope: true, directive with transclude: true
        創建新的 Scope,但不繼承:directive with scope: { ... }。它會創建一個獨立 Scope。
        注:默認情況下 directive 不創建新 Scope,即默認參數是 scope: false。

        ng-include
        

        假設在我們的 controller 中,

        HTML 為:

        
        

        輸入(比如”77″)到第一個 input 文本框,則子 Scope 將獲得一個新的 myPrimitive 屬性,覆蓋掉父 Scope 的同名屬性。這可能和你預想的不一樣。

        201614151107899.png (541×124)

        輸入(比如”99″)到第二個 input 文本框,并不會在子 Scope 創建新的屬性,因為 tpl2.html 將 model 綁定到了一個對象屬性(an object property),原型繼承在這時發揮了作用,ngModel 尋找對象 myObject 并且在它的父 Scope 中找到了。

        201614151132150.png (541×124)

        如果我們不想把 model 從 number 基礎類型改為對象,我們可以用 $parent 改寫第一個模板:

        輸入(比如”22″)到這個文本框也不會創建新屬性了。model 被綁定到了父 scope 的屬性上(因為 $parent 是子 Scope 指向它的父 Scope 的一個屬性)。

        201614151212469.png (541×117)

        對于所有的 scope (原型繼承的或者非繼承的),Angular 總是會通過 Scope 的 $parent, $$childHead 和 $$childTail 屬性記錄父-子關系(也就是繼承關系),圖中為簡化而未畫出這些屬性。

        在沒有表單元素的情況下,另一種方法是在父 Scope 中定義一個函數來修改基本數據類型。因為有原型繼承,子 Scope 確保能夠調用這個函數。例如,

        查看 DEMO

        ng-switch
        ng-switch 的原型繼承和 ng-include 一樣。所以如果你需要對基本類型數據進行雙向綁定,使用 $parent,或者將其改為 object 對象并綁定到對象的屬性,防止子 Scope 覆蓋父 Scope 的屬性。
        ng-repeat
        ng-repeat 有一點不一樣。假設在我們的 controller 里:

        還有 HTML:

        
         
      1. 對于每一個 Item,ng-repeat 創建新的 Scope,每一個 Scope 都繼承父 Scope,但同時 item 的值也被賦給了新 Scope 的新屬性(新屬性的名字為循環的變量名)。Angular ng-repeat 的源碼實際上是這樣的:

        如果 item 是一個基礎數據類型(就像 myArrayOfPrimitives),本質上它的值被復制了一份賦給了新的子 scope 屬性。改變這個子 scope 屬性值(比如用 ng-model,即 num)不會改變父 scope 引用的 array。所以上面第一個 ng-repeat 里每一個子 scope 獲得的 num 屬性獨立于 myArrayOfPrimitives 數組:

        201614151333896.png (440×153)

        這樣的 ng-repeat 和你預想中的不一樣。在 Angular 1.0.2 及更早的版本,向文本框中輸入會改變灰色格子的值,它們只在子 Scope 中可見。Angular 1.0.3+ 以后,輸入文本不會再有任何作用了。
        我們希望的是輸入能改變 myArrayOfPrimitives 數組,而不是子 Scope 里的屬性。為此我們必須將 model 改為一個關于對象的數組(array of objects)。

        所以如果 item 是一個對象,則對于原對象的一個引用(而非拷貝)被賦給了新的子 Scope 屬性。改變子 Scope 屬性的值(使用 ng-model,即 obj.num)也就改變了父 Scope 所引用的對象。所以上面第二個 ng-repeat 可表示為:

        201614151355015.png (560×152)

        這才是我們想要的。輸入到文本框即會改變灰色格子的值,該值在父 Scope 和子 Scope 均可見。
        ng-controller
        使用 ng-controller 進行嵌套,結果和 ng-include 和 ng-switch 一樣是正常的原型繼承。所以做法也一樣不再贅述。然而“兩個 controller 使用 $scope 繼承來共享信息被認為是不好的做法”
        應該使用 service 在 controller 間共享數據。

        如果你確實要通過繼承來共享數據,那么也沒什么特殊要做的,子 Scope 可以直接訪問所有父 Scope 的屬性。
        directives
        這個要分情況來討論。

        默認 scope: false – directive 不會創建新的 Scope,所以沒有原型繼承。這看上去很簡單,但也很危險,因為你會以為 directive 在 Scope 中創建了一個新的屬性,而實際上它只是用到了一個已存在的屬性。這對編寫可復用的模塊和組件來說并不好。
        scope: true – 這時 directive 會創建一個新的子 scope 并繼承父 scope。如果在同一個 DOM 節點上有多個 directive 都要創建新 scope,則只有一個新 Scope 會創建。因為有正常的原型繼承,所以和 ng-include, ng-switch 一樣要注意基礎類型數據的雙向綁定,子 Scope 屬性會覆蓋父 Scope 同名屬性。
        scope: { ... } – 這時 directive 創建一個獨立的 scope,沒有原型繼承。這在編寫可復用的模塊和組件時是比較好的選擇,因為 directive 不會不小心讀寫父 scope。然而,有時候這類 directives 又經常需要訪問父 scope 的屬性。對象散列(object hash)被用來建立這個獨立 Scope 與父 Scope 間的雙向綁定(使用 ‘=')或單向綁定(使用 ‘@')。還有一個 ‘&' 用來綁定父 Scope 的表達式。這些統統從父 Scope 派生創建出本地的 Scope 屬性。注意,HTML 屬性被用來建立綁定,你無法在對象散列中引用父 Scope 的屬性名,你必須使用一個 HTML 屬性。例如, 和 scope: { localProp: '@parentProp' } 是無法綁定父屬性 parentProp 到獨立 scope的,你必須這樣指定: 以及 scope: { localProp: '@theParentProp' }。獨立的 scope 中 __proto__ 引用了一個 Scope 對象(下圖中的桔黃色 Object),獨立 scope 的 $parent 指向父 scope,所以盡管它是獨立的而且沒有從父 Scope 原型繼承,它仍然是一個子 scope。

        下面的圖中,我們有 和 scope:

        同時,假設 directive 在它的 link 函數里做了 scope.someIsolateProp = "I'm isolated"

        201614151506832.png (467×157)

        注意:在 link 函數中使用 attrs.$observe('attr_name', function(value) { ... } 來獲取獨立 Scope 用 ‘@' 符號替換的屬性值。例如,在 link 函數中有 attrs.$observe('interpolated', function(value) { ... } 值將被設為 11. (scope.interpolatedProp 在 link 函數中是 undefined,相反scope.twowayBindingProp 在 link 函數中定義了,因為用了 ‘=' 符號)
        transclude: true – 這時 directive 創建了一個新的 “transcluded” 子 scope,同時繼承父 scope。所以如果模板片段中的內容(例如那些將要替代 ng-transclude 的內容)要求對父 Scope 的基本類型數據進行雙向綁定,使用 $parent,或者將 model 一個對象的屬性,防止子 Scope 屬性覆蓋父 Scope 屬性。

        transcluded 和獨立 scope (如果有)是兄弟關系,每個 Scope 的 $parent 指向同一個父 Scope。當模板中的 scope 和獨立 Scope 同時存在,獨立 Scope 屬性 $$nextSibling 將會指向模板中的 Scope。
        在下圖中,假設 directive 和上個圖一樣,只是多了 transclude: true

        201614151536198.png (640×226)

        查看 在線 DEMO,例子里有一個 showScope() 函數可以用來檢查獨立 Scope 和它關聯的 transcluded scope。
        總結
        一共有四種 Scope:

        普通進行原型繼承的 Scope —— ng-include, ng-switch, ng-controller, directive with scope: true
        普通原型繼承的 Scope 但拷貝賦值 —— ng-repeat。 每個 ng-repeat 的循環都創建新的子 Scope,并且子 Scope 總是獲得新的屬性。
        獨立的 isolate scope —— directive with scope: {...}。它不是原型繼承,但 ‘=', ‘@' 和 ‘&' 提供了訪問父 Scope 屬性的機制。
        transcluded scope —— directive with transclude: true。它也遵循原型繼承,但它同時是任何 isolate scope 的兄弟。
        對于所有的 Scope,Angular 總是會通過 Scope 的 $parent, $$childHead 和 $$childTail 屬性記錄父-子關系。

        PS:scope和rootscope的區別
        scope是html和單個controller之間的橋梁,數據綁定就靠他了。rootscope是各個controller中scope的橋梁。用rootscope定義的值,可以在各個controller中使用。下面用實例詳細的說明一下。
        1,js代碼

        2,html代碼

         
         I set the global variable.{{$root.name}} 
         
         
         
         1,get global variable .{{name}}
        2,get global variable .{{$root.name}}

        3,顯示結果

        I set the global variable.this is test 
        1,get global variable .this is test 
        2,get global variable .this is test 
        

        由結果可以看出來,$rootScope.name設置的變量,在所有controller里面都是可以直接用{{$root.name}}來顯示的,很強大。那當然也可以賦值給scope.

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        深入探究AngularJS框架中Scope對象的超級教程_AngularJS

        深入探究AngularJS框架中Scope對象的超級教程_AngularJS:一、遇到的問題 問題發生在使用 AngularJS 嵌套 Controller 的時候。因為每個 Controller 都有它對應的 Scope(相當于作用域、控制范圍),所以 Controller 的嵌套,也就意味著 Scope 的嵌套。這個時候如果兩個 Scope 內都有同名的 Model 會發
        推薦度:
        標簽: 教程 scope 框架
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 四虎在线最新永久免费| 免费国产黄网站在线观看视频 | 久久亚洲精品专区蓝色区| 免费一区二区三区| 久久精品国产亚洲AV麻豆不卡 | 2020久久精品亚洲热综合一本| 中文字幕亚洲免费无线观看日本 | 亚洲AV日韩精品久久久久| 久久免费美女视频| 久久精品亚洲中文字幕无码麻豆| 久久免费区一区二区三波多野| 久久99亚洲网美利坚合众国| free哆啪啪免费永久| 亚洲va成无码人在线观看| 免费在线看v网址| 亚洲国产精品ⅴa在线观看| 国产又大又黑又粗免费视频| 美女被吸屁股免费网站| 亚洲色WWW成人永久网址| 无码国产精品一区二区免费式芒果 | 亚洲欧美日本韩国| 亚洲精品国产精品国自产观看 | 超清首页国产亚洲丝袜| 免费毛片a线观看| 亚洲第一成人在线| 亚洲 另类 无码 在线| 久久国产一片免费观看| 亚洲蜜芽在线精品一区| 国内自产拍自a免费毛片| 一区免费在线观看| 亚洲专区先锋影音| 国产成人免费片在线观看| 中文字幕无码免费久久9一区9| 亚洲毛片一级带毛片基地| 日本不卡高清中文字幕免费| jizz免费观看视频| 亚洲另类图片另类电影| 亚洲第一区在线观看| xx视频在线永久免费观看| 免费无毒a网站在线观看| 久久久久亚洲AV无码专区首JN|