AngularJS 中範圍原型/原型繼承的細微差別是什麼?
快速回答:
子作用域通常繼承自其父作用域,但並非總是如此。此規則的例外是範圍為 { ... } 的指令-這會建立一個不典型繼承的「隔離」範圍。在建立「可重複使用元件」指令時經常使用此構造。
關於細微差別,範圍繼承通常很簡單......直到您需要雙向資料綁定(例如,表單elements, ng-model) 在子作用域中。如果您嘗試從子作用域內綁定到父作用域中的基元(例如數字、字串、布林值),ng-repeat、ng-switch 和ng-include 可能會讓您陷入困境。它並不像大多數人期望的那樣工作。子作用域擁有自己的屬性,該屬性隱藏/隱藏同名的父屬性。您的解決方法是:
L-o-n-g 答:
L-o-n-g 答:理解原型繼承
在討論範圍繼承之前了解原型繼承非常重要。
假設parentScope 具有屬性aString、aNumber、anArray、anObject 和aFunction。如果childScope原型繼承自parentScope,我們有:
[原型繼承圖的圖像]
如果我們嘗試從子作用域存取parentScope上定義的屬性,JavaScript將首先尋找在子作用域中,找不到該屬性,然後在繼承作用域中尋找,並找到該屬性。 (如果它在父作用域中沒有找到該屬性,它將沿著原型鏈繼續向上......一直到根作用域)。所以,這些都是真的:
假設我們這樣做:不參考原型鏈,並在 childScope 中新增一個新的 aString 屬性。這個新屬性隱藏/隱藏了同名的parentScope屬性。當我們下面討論 ng-repeat 和 ng-include 時,這一點將變得非常重要。
[屬性隱藏圖的圖像]
假設我們這樣做:
由於在childScope 中未找到物件(anArray 和anObject),因此查閱了原型鏈。在parentScope 中找到對象,並在原始對像上更新屬性值。 childScope 中沒有新增屬性;沒有建立新物件。 (請注意,在JavaScript 中陣列和函數也是物件。)
[遵循原型鏈圖的圖像]
假設我們這樣做:
不參考原型鏈,子作用域取得兩個新的物件屬性,這些屬性隱藏/隱藏具有相同名稱的父作用域物件屬性。
[Image更多屬性隱藏圖]
Angular作用域繼承
競爭者:
預設情況下,指令不會建立新作用域(即,scope: false)。
ng-include
假設我們的控制器中有:
並且在我們的HTML 中:
並且在我們的HTML 中:
每個ng-include 都會產生一個新的子作用域,其原型繼承自父作用域。 [ng-include 子作用域圖的圖像]在第一個輸入文字方塊中鍵入(例如「77」)會導致子作用域獲得一個新的myPrimitive 作用域屬性,該屬性隱藏/隱藏同名的父作用域屬性。 [帶有原始圖的 ng-include 圖像]在第二個輸入文字方塊中鍵入(例如「99」)不會產生一個新的子屬性。因為 tpl2.html 將模型綁定到物件屬性,所以當 ngModel 尋找物件 myObject 時,原型繼承就會啟動——它在父作用域中找到它。 [帶有物件圖的ng-include 圖像]
如果我們不想將模型從原始模型更改為原始模型,我們可以重寫第一個模板以使用$parent object:
在此輸入文字方塊中鍵入(例如「22」)不會產生新的子屬性。該模型現在綁定到父作用域的屬性(因為 $parent 是引用父作用域的子作用域屬性)。[ng-include 與 $parent 圖的圖像]
ng-開關NG-switch 作用域繼承的工作方式與 ng-include 類似。因此,如果您需要與父作用域中的原語進行 2 路資料綁定,請使用 $parent,或將模型變更為對象,然後綁定到該對象的屬性。這將避免子作用域隱藏/隱藏父作用域屬性。
ng-repeat
NG-repeat 的工作方式略有不同。假設我們的控制器中有:
並且在HTML 中:
對於每個項目/迭代,ng-repeat 創建一個新範圍,其原型繼承自父級作用域,但它也會將項目的值指派給新子作用域上的新屬性(新屬性是循環變數名稱)。以下是 ng-repeat 的 Angular 原始碼實際內容:
如果該項目是基元(如 myArrayOfPrimitives 中),則本質上會將值的副本分配給新的子作用域屬性。變更子作用域屬性的值(即使用 ng-model,因此使用子作用域 num)不會變更父作用域所引用的陣列。因此,在上面的第一個ng-repeat 中,每個子作用域都會獲得一個獨立於myArrayOfPrimitives 數組的num 屬性:
[帶有基元圖的ng-repeat 圖像]
這個ng-repeat不會起作用(就像你想要/期望的那樣)。在文字方塊中鍵入內容會變更灰色方塊中的值,這些值僅在子範圍中可見。我們想要的是輸入影響 myArrayOfPrimitives 數組,而不是子範圍基元屬性。為了實現這一點,我們需要將模型更改為物件數組。
因此,如果該項目是一個對象,則將對原始對象(而不是副本)的引用分配給新的子作用域財產。變更子作用域屬性的值(即使用 ng-model,因此使用 obj.num)確實會變更父作用域所引用的物件。因此,在上面的第二個ng-repeat 中,我們有:
[帶有物件圖的ng-repeat 圖像]
(我將一條線塗成灰色,以便清楚地顯示在哪裡)它正在運行。 )
這如預期般運作。輸入
以上是原型繼承如何與 AngularJS 作用域中的雙向資料綁定一起工作?的詳細內容。更多資訊請關注PHP中文網其他相關文章!