国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題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關(guān)鍵字專題關(guān)鍵字專題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
當(dāng)前位置: 首頁 - 科技 - 知識(shí)百科 - 正文

深入探究AngularJS框架中Scope對(duì)象的超級(jí)教程_AngularJS

來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 21:48:19
文檔

深入探究AngularJS框架中Scope對(duì)象的超級(jí)教程_AngularJS

深入探究AngularJS框架中Scope對(duì)象的超級(jí)教程_AngularJS:一、遇到的問題 問題發(fā)生在使用 AngularJS 嵌套 Controller 的時(shí)候。因?yàn)槊總€(gè) Controller 都有它對(duì)應(yīng)的 Scope(相當(dāng)于作用域、控制范圍),所以 Controller 的嵌套,也就意味著 Scope 的嵌套。這個(gè)時(shí)候如果兩個(gè) Scope 內(nèi)都有同名的 Model 會(huì)發(fā)
推薦度:
導(dǎo)讀深入探究AngularJS框架中Scope對(duì)象的超級(jí)教程_AngularJS:一、遇到的問題 問題發(fā)生在使用 AngularJS 嵌套 Controller 的時(shí)候。因?yàn)槊總€(gè) Controller 都有它對(duì)應(yīng)的 Scope(相當(dāng)于作用域、控制范圍),所以 Controller 的嵌套,也就意味著 Scope 的嵌套。這個(gè)時(shí)候如果兩個(gè) Scope 內(nèi)都有同名的 Model 會(huì)發(fā)
一、遇到的問題
問題發(fā)生在使用 AngularJS 嵌套 Controller 的時(shí)候。因?yàn)槊總€(gè) Controller 都有它對(duì)應(yīng)的 Scope(相當(dāng)于作用域、控制范圍),所以 Controller 的嵌套,也就意味著 Scope 的嵌套。這個(gè)時(shí)候如果兩個(gè) Scope 內(nèi)都有同名的 Model 會(huì)發(fā)生什么呢?從子 Scope 怎樣更新父 Scope 里的 Model 呢?

這個(gè)問題很典型,比方說當(dāng)前頁面是一個(gè)產(chǎn)品列表,那么就需要定義一個(gè) ProductListController

你大概看到了在 Scope 里還定義了一個(gè) selectedProduct 的 Model,表示選中了某一個(gè)產(chǎn)品。這時(shí)會(huì)獲取該產(chǎn)品詳情,而頁面通過 AngularJS 中的 $routeProvider 自動(dòng)更新,拉取新的詳情頁模板,模板中有一個(gè) ProductDetailController

有趣的事情發(fā)生了,在這里也有一個(gè) selectedProduct ,它會(huì)怎樣影響 ProductListController 中的 selectedProduct 呢?

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

二、解決的辦法
解決的辦法就是不使用基本數(shù)據(jù)類型,而在 Model 里永遠(yuǎn)多加一個(gè)點(diǎn).

使用

來替代

是不是很坑爹?下面這個(gè)例子很明確地表達(dá)了我所想表達(dá)的奇葩現(xiàn)象

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

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

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

201614150604637.png (619×257)

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

假設(shè)我們執(zhí)行下面的語句

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

201614150634794.png (619×257)

假設(shè)我們執(zhí)行這個(gè)操作:

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

201614150658628.png (608×257)

假設(shè)我們執(zhí)行這個(gè)操作:

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

201614150718718.png (608×320)

應(yīng)該可以總結(jié)

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

我們從 childScope 刪除了屬性,則當(dāng)我們?cè)俅卧L問該屬性時(shí),原型鏈會(huì)被查詢。刪除對(duì)象的屬性會(huì)讓來自原型鏈中的屬性浮現(xiàn)出來。

201614150741147.png (608×320)

四、AngularJS 的 Scope 繼承
創(chuàng)建新的 Scope,并且原型繼承:ng-repeat, ng-include, ng-switch, ng-view, ng-controller, directive with scope: true, directive with transclude: true
創(chuàng)建新的 Scope,但不繼承:directive with scope: { ... }。它會(huì)創(chuàng)建一個(gè)獨(dú)立 Scope。
注:默認(rèn)情況下 directive 不創(chuàng)建新 Scope,即默認(rèn)參數(shù)是 scope: false。

ng-include

假設(shè)在我們的 controller 中,

HTML 為:


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

201614151107899.png (541×124)

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

201614151132150.png (541×124)

如果我們不想把 model 從 number 基礎(chǔ)類型改為對(duì)象,我們可以用 $parent 改寫第一個(gè)模板:

輸入(比如”22″)到這個(gè)文本框也不會(huì)創(chuàng)建新屬性了。model 被綁定到了父 scope 的屬性上(因?yàn)?$parent 是子 Scope 指向它的父 Scope 的一個(gè)屬性)。

201614151212469.png (541×117)

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

在沒有表單元素的情況下,另一種方法是在父 Scope 中定義一個(gè)函數(shù)來修改基本數(shù)據(jù)類型。因?yàn)橛性屠^承,子 Scope 確保能夠調(diào)用這個(gè)函數(shù)。例如,

查看 DEMO

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

還有 HTML:


 
  • 對(duì)于每一個(gè) Item,ng-repeat 創(chuàng)建新的 Scope,每一個(gè) Scope 都繼承父 Scope,但同時(shí) item 的值也被賦給了新 Scope 的新屬性(新屬性的名字為循環(huán)的變量名)。Angular ng-repeat 的源碼實(shí)際上是這樣的:

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

    201614151333896.png (440×153)

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

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

    201614151355015.png (560×152)

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

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

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

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

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

    201614151506832.png (467×157)

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

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

    201614151536198.png (640×226)

    查看 在線 DEMO,例子里有一個(gè) showScope() 函數(shù)可以用來檢查獨(dú)立 Scope 和它關(guān)聯(lián)的 transcluded scope。
    總結(jié)
    一共有四種 Scope:

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

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

    2,html代碼

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

    3,顯示結(jié)果

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

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

    聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    深入探究AngularJS框架中Scope對(duì)象的超級(jí)教程_AngularJS

    深入探究AngularJS框架中Scope對(duì)象的超級(jí)教程_AngularJS:一、遇到的問題 問題發(fā)生在使用 AngularJS 嵌套 Controller 的時(shí)候。因?yàn)槊總€(gè) Controller 都有它對(duì)應(yīng)的 Scope(相當(dāng)于作用域、控制范圍),所以 Controller 的嵌套,也就意味著 Scope 的嵌套。這個(gè)時(shí)候如果兩個(gè) Scope 內(nèi)都有同名的 Model 會(huì)發(fā)
    推薦度:
    標(biāo)簽: 教程 scope 框架
    • 熱門焦點(diǎn)

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 成人国内精品久久久久影院 | 一本综合久久国产二区 | 欧美日韩精品一区二区在线播放 | 精品国产乱码一区二区三区麻豆 | 欧美日韩精品一区二区三区视频在线 | 韩国一区| 国产免费一区二区三区香蕉精 | 永久毛片 | 国产日韩欧美视频在线 | 99精品欧美一区二区三区综合在线 | 欧美成人精品高清在线播放 | 国产自在自线午夜精品视频 | 国产精品123区 | 国产在线精品一区二区夜色 | 中文字幕久久亚洲一区 | 日b毛片| 久久一区二区三区四区 | 五月天婷婷久久 | 国产精品不卡 | 国产毛片视频 | 亚洲日本激情综合在线观看 | 国产一区二区三区视频 | 欧美日韩性生活 | 亚洲国产成人久久综合一区 | 91热成人精品国产免费 | 真实的和子乱拍在线观看 | 国产一区二区三区毛片 | 欧美日韩一区二区三区久久 | 欧美在线一区二区 | 欧美日韩亚洲天堂 | 国内精品伊人久久久久 | 日本成人一级 | 免费看男女做好爽好硬视频 | 日韩欧美在线综合 | 高清国产一区 | 99热伊人| 国产在线播放一区 | 国产精品亚洲四区在线观看 | 欧美国产综合 | 最新亚洲精品 | 91精品国产91热久久p |