31

给定一个带有 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 10app.js使其使用共享范围工作。

4

3 回答 3

29

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

ng-transclude旨在允许指令处理任意内容,并且隔离范围旨在允许指令封装其数据。

如果ng-transclude不保留这样的范围,则您要包含的任何任意内容都需要知道指令的实现细节(即,它需要知道您创建的隔离范围上可用的内容)。

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

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

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


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

“在典型的设置中,小部件创建一个隔离范围,但嵌入不是子范围,而是隔离范围的兄弟。这使得小部件可以具有私有状态,并且嵌入可以绑定到父级(预隔离)范围。”

于 2013-07-22T17:38:21.633 回答
12

您可以手动嵌入子元素

link: function(scope, element, attrs, ctrl, transclude) {
    transclude(scope, function(clone, scope) {
        element.find('.transclude-placeholder').append(clone);
    });
}
于 2014-08-07T08:35:35.973 回答
5

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

自 Angular v1.3 以来,行为发生了变化,现在它的行为与问题的“我预期”部分中描述的完全一样,使得这个问题对于 Angular v1.3+ 来说已经过时了。

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

于 2015-04-30T14:15:59.960 回答