2013-08-05 36 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范围继承。