这个问题很老,所以你可能找到了答案,但我仍然会试图解释它,因为其他人可能会觉得它有用。
使用隔离示波器并使用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
范围继承。