2013-08-05 86 views
1

我遇到了隔離指令和嵌套的包含問題,並希望有些人可以啓發我,瞭解發生了什麼。問題AngularJS嵌套的包含和隔離範圍

概括地說,我有兩個指令,每個都有自己的分離範圍

  • 一個與模板<div b><div ng-transclude></div></div>
  • b相此模板<div><div ng-transclude></div><div>

當我使用

  • <div a>{{greeting}}</div>然後招呼不顯示
  • <div a>{{somePrivatePropertyOfA>></div>話,我可以看到分離範圍的財產。

如果指令的作用域不是孤立的,那麼私有屬性不會泄漏並顯示問候語。

我創建了一個plnkr example,它更詳細地說明了我想要做的事情。它還表明隔離作用域的私有屬性泄漏到模板中。

我認爲這個問題可以通過編寫我自己的編譯函數來解決,但我想了解爲什麼transcluded內容最終被綁定到或繼承自指令a的隔離範圍。

回答

1

這個問題很老,所以你可能找到了答案,但我仍然會試圖解釋它,因爲其他人可能會覺得它有用。

使用隔離示波器並使用ng-transclude指令處理內容時,需要記住三件事。

  1. 隔離範圍意味着它不會繼承其父項的屬性。它只繼承你在scope對象內顯式綁定的屬性。
  2. 變形內容只有在插入後纔會被編譯和鏈接。
  3. ng-transclude創建指令的新同級作用域,它跨越了內容。雖然這可能會從版本1.3.0 ng-transclude should not create new sibling scope更改。

瞭解您的示例中發生的事情的最佳方法是查看範圍樹。

< Scope (002) : ng-app 
    < Scope (003) ng-controller 
     < Scope (004) : b 
     < Scope (005) : ng-transclude <--- Content rendered under this scope 
     < Scope (006) : aIsolated 
      < Scope (007) : b 
      < Scope (008) : ng-transclude 
       < Scope (009) : ng-transclude <--- Content rendered under this scope 
     < Scope (00A) : aNotIsolated 
      < Scope (00B) : b 
      < Scope (00C) : ng-transclude 
       < Scope (00D) : ng-transclude <--- Content rendered under this scope 

在您的第一個示例中,Angular發現b指令。它撕掉內容,創建一個獨立的範圍並編譯其模板。編譯模板時會發現ng-transclude指令。它創建一個新的同級作用域並將其內容插入到其中。由於ng-transclude的範圍是兄弟姐妹,其父母是ng-controller。因此,內容會繼承您的MainCtrl控制器的所有屬性。

在第二個示例中,Angular找到了aIsolated指令。它撕掉內容,創建一個獨立的範圍並編譯其模板。編譯模板時,它會找到b指令並開始編譯b。它撕掉b指令包裝的內容,爲b創建一個獨立的子範圍並編譯模板。編譯b模板時,會發現ng-transclude指令。它創建一個新的同級作用域並將其內容插入到其中。即這個新的兄弟範圍被傳遞給transclude函數,該函數使內容成爲ng-transclude範圍的子項。然後它開始編譯內容,在該內容中找到另一個ng-transclude指令,以便它創建一個新的作用域,並將其中的{{message}}{{private}}表達式插入其中。最後它會編譯和鏈接表達式。但是如果你看看繼承樹,你會發現內容繼承了aIsolated作用域的屬性,這使我們可以看到獨立的作用域。

aIsolated指令具有隔離範圍,因此它無法訪問父範圍中定義的private屬性,因此該內容將讀取您在aIsolated控制器中定義的屬性。指令b然後創建一個獨立的範圍,並添加一個private屬性,但因爲它是隔離它不覆蓋其父母的屬性。因此,當所有指令完成編譯和鏈接時,將在aIsolated指令中定義的屬性放入{{message}}{{private}}表達式中。 message屬性不存在,因此它是空的。

第三個示例的編譯過程與第二個示例的編譯過程完全相同。它僅與aNotIsolated指令有所不同,該指令僅創建自己的作用域,從而繼承了控制器中定義的屬性。

如果指令的範圍不是孤立的,那麼私有財產不 不漏通過和問候所示。

這並不完全正確。它可能以這種方式出現的原因是因爲aNotIsolated未定義它自己的private屬性。在這裏my exampleaNotIsolated在其控制器中定義了private屬性,因此您可以看到私人消息與您的示例不同。

漏水並不是一個很好的詞來描述發生的事情。表達式在它們被插入的範圍內進行評估。因此{{message}}{{private}}表達式在ng-transclude範圍內進行評估,該範圍繼而從MainCtrl,aIsolatedaNotIsolated範圍繼承。