1

我遇到了隔离指令和嵌套嵌入的问题,希望有些人可以启发我了解正在发生的事情。

简而言之,我有两个指令,每个指令都有自己的隔离范围

  • 一个带模板的<div b><div ng-transclude></div></div>
  • b 用这个模板<div><div ng-transclude></div><div>

当我使用

  • <div a>{{greeting}}</div> 然后问候不显示
  • <div a>{{somePrivatePropertyOfA>></div>然后我可以看到隔离范围的属性。

如果指令的范围不是孤立的,那么私有属性不会泄漏并显示问候语。

我创建了一个plnkr 示例,更详细地说明了我正在尝试做的事情。它还表明隔离范围的私有属性泄漏到模板中。

我认为这个问题可以通过编写我自己的编译函数在我的特定情况下解决,但我想了解为什么嵌入的内容最终被绑定到或继承自指令 a 的隔离范围

4

1 回答 1

1

这个问题已经很老了,所以你可能找到了答案,但我仍然会尝试解释它,因为其他人可能会觉得它很有用。

在使用隔离范围和使用ng-transclude指令嵌入内容时,需要记住三件事。

  1. 隔离范围意味着它不继承其父级的属性。它仅继承您在范围对象内显式绑定的属性。
  2. 嵌入的内容只有在插入后才会被编译和链接。
  3. ng-transclude创建包含内容的指令的新同级范围。虽然,这可能会从版本 1.3.0 更改ng-transclude 不应创建新的同级范围

了解示例中发生的情况的最佳方法是查看您的范围树。

< 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指令简单地创建自己的范围,从而继承MainCtrl控制器中定义的属性。

如果指令的范围不是孤立的,那么私有属性不会泄漏并显示问候语。

这并不完全正确。它可能以这种方式出现的原因是因为aNotIsolated没有定义自己的private属性。在我的示例 aNotIsolated中,在其控制器中定义了private属性,因此您可以看到私人消息与您的示例不同。

泄漏也不是描述正在发生的事情的好词。表达式在它们被插入的范围内进行评估。所以{{message}}and{{private}}表达式在作用域下进行评估,ng-transclude而作用域又继承自MainCtrl,aIsolatedaNotIsolated作用域。

于 2013-12-19T16:03:03.657 回答