首頁 >web前端 >js教程 >原型繼承如何與 AngularJS 作用域中的雙向資料綁定一起工作?

原型繼承如何與 AngularJS 作用域中的雙向資料綁定一起工作?

Susan Sarandon
Susan Sarandon原創
2024-12-26 11:51:10725瀏覽

How Does Prototypal Inheritance Work with Two-Way Data Binding in AngularJS Scopes?

AngularJS 中範圍原型/原型繼承的細微差別是什麼?

快速回答:

子作用域通常繼承自其父作用域,但並非總是如此。此規則的例外是範圍為 { ... } 的指令-這會建立一個不典型繼承的「隔離」範圍。在建立「可重複使用元件」指令時經常使用此構造。

關於細微差別,範圍繼承通常很簡單......直到您需要雙向資料綁定(例如,表單elements, ng-model) 在子作用域中。如果您嘗試從子作用域內綁定到父作用域中的基元(例如數字、字串、布林值),ng-repeat、ng-switch 和ng-include 可能會讓您陷入困境。它並不像大多數人期望的那樣工作。子作用域擁有自己的屬性,該屬性隱藏/隱藏同名的父屬性。您的解決方法是:

  1. 在模型的父級中定義對象,然後在子級中引用該對象的屬性:parentObj.someProp
  2. 使用$parent.parentScopeProperty (並不總是可能,但比 1更容易。人員通常沒有意識到ng-repeat、ng-switch、ng-view、ng-include 和ng-if都會建立新的子作用域,所以問題當涉及到這些指令時經常會出現。 (請參閱此範例以快速說明問題。)
  3. 透過遵循始終使用“.”的“最佳實踐”,可以輕鬆避免原語的此問題。在您的 ng-models 中 – 觀看 3 分鐘。 Misko 示範了 ng-switch 的原始綁定問題。
有一個「.」在您的模型中將確保原型繼承發揮作用。所以,使用:

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作用域繼承

競爭者:

  • 原型繼承:ng-重複、ng-include、ng-switch、ng-controller、指令範圍: true,指令包含:true。
  • 隔離範圍:指令範圍:{ ... }。這會建立一個「隔離」作用域。

預設情況下,指令不會建立新作用域(即,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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:IVR下一篇:IVR