为什么ng-transclude的范围不是其指令范围的子代 - 如果指令具有隔离范围?

时间:2013-07-22 13:00:25

标签: angularjs

给定带有transclude和隔离范围的指令(container1),当链接指令时,我有这些范围:

Scope 004           <-- scope of the body
    Scope 005       <-- scope of directive container1
    Scope 006       <-- scope of the ng-transclude

我期待:

Scope 004            <-- scope of the body
    Scope 005        <-- scope of the directive
         Scope 006   <-- scope of the ng-transclude

如果同一指令有共享范围而不是隔离范围,我会得到预期的结果。

这会给我带来一个问题,因为如果被转换的内容包含另一个带有隔离范围的指令(component1),我会得到:

Scope 004             <-- scope of the body
    Scope 005         <-- scope of the directive
    Scope 006         <-- scope of the ng-transclude
          Scope 007   <-- scope of directive component1

我想使用这样的指令:

<container1>
   <component1 data="objectExposedInContainer1"/>
</container1>

但是这不起作用,在component1内,$scope.dataundefined,因为objectExposedInContainer1不在正确的范围内。

我有两个问题:

  • 如果指令具有隔离范围,为什么ng-transclude的范围不是其指令范围的子节点?这是一个错误吗?
  • 如果不是错误,容器指令怎样才能将数据传递给它的内容,如果不是通过设置我尝试过的属性。

以下是不起作用的示例:http://plnkr.co/edit/NDmJiRzTF9e5gw8Buht2?p=preview。因为Plunker是用Anguar构建的,所以用Batarang很难调试。我建议在本地下载代码。注释掉line 10 app.js以使其使用共享范围。

3 个答案:

答案 0 :(得分:29)

  

如果指令具有隔离范围,为什么ng-transclude的范围不是其指令范围的子节点?

ng-transclude旨在允许指令使用任意内容,而隔离范围旨在允许指令封装其数据。

如果ng-transclude没有保留这样的范围,那么您要转换的任意内容都需要知道您的指令的实现细节(即,它需要知道您创建的隔离范围上可用的内容)。

  

如果不是错误,容器指令如何通过设置我尝试过的属性来将数据传递给它的内容。

如果容器指令和包含的指令是耦合的 - 即你写了两个并且需要它们一起行动 - 那么它们应该通过共享控制器进行通信。

如果容器指令应该将内容注入子项的范围(例如ng-repeat),那么您不应该使用隔离的范围。


角度文档非常清楚应该是什么行为:

  

“在典型的设置中,小部件创建了一个隔离范围,但是   transclusion不是一个孩子,而是一个孤立范围的兄弟。这个   使得窗口小部件可以具有私有状态,以及   转换为绑定到父(预隔离)范围。“

答案 1 :(得分:12)

您可以手动转换子元素

link: function(scope, element, attrs, ctrl, transclude) {
    transclude(scope, function(clone, scope) {
        element.find('.transclude-placeholder').append(clone);
    });
}

答案 2 :(得分:4)

最佳答案仅适用于Angular v1.2。

自Angular v1.3开始,行为发生了变化,现在它的行为与&#34;我期望的&#34;问题的一部分,使这个问题在Angular v1.3 +中已经过时。

来源:https://github.com/angular/angular.js/commit/fb0c77f0b66ed757a56af13f81b943419fdcbd7f