這個問題很老,所以你可能找到了答案,但我仍然會試圖解釋它,因爲其他人可能會覺得它有用。
使用隔離示波器並使用ng-transclude
指令處理內容時,需要記住三件事。
- 隔離範圍意味着它不會繼承其父項的屬性。它只繼承你在scope對象內顯式綁定的屬性。
- 變形內容只有在插入後纔會被編譯和鏈接。
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
,aIsolated
或aNotIsolated
範圍繼承。