【问题标题】:Nested - transcluded items - scope clarification?嵌套 - 嵌入项目 - 范围澄清?
【发布时间】:2016-03-13 18:23:48
【问题描述】:

我已经知道嵌入是如何工作的(我猜只是在第一级),但是我对嵌套嵌入项的范围有疑问。

好的,我有这个代码:

<body ng-app="docsTabsExample" ng-controller="ctrl">
  <my-tabs>
    <my-pane title="Hello">
      <h4>Hello , The value of "i" is => {{i}}</h4>
   </my-pane>
  </my-tabs>
</body>

基本上我有一个controller&lt;my-tabs&gt;&lt;my-pane &gt;

查看myTabs 指令:

  .directive('myTabs', function()
  {
      return {
          restrict: 'E',
          transclude: true,
          scope:
          {},
          controller: ['$scope', function($scope)
          {
              $scope.i = 2;
          }],
          template: '<div ng-transclude></div>'
      };
  })

我知道指令的内容可以访问outer指令的作用域

所以黄色部分将可以访问外部范围(即主控制器范围):

这是myPane 指令的代码:

  .directive('myPane', function()
  {
      return {
          require: '^myTabs',
          restrict: 'E',
          transclude: true,
          scope:
          {
          },
          controller: function($scope)
          {
              $scope.i = 4; //different value
          },
          template: '<div  ng-transclude></div>'
      };
  })

程序开始于:

.controller('ctrl', function($scope)
{
    $scope.i = 1000;
})

程序的输出是:

你好,“i”的值是=> 1000

但是

根据文档:myPane's 转入数据应该可以访问指令的外部范围,即 myTabs 指令,其值为 i=2

但是myPane 有一个隔离 范围,所以它确实myTabs 继承范围。

问题

那么为了得到i=1000,它是否会比控制器的范围高一级更多?? (澄清,我不是在问如何让i 获得另一个值 - 我是在问为什么/如何它具有 1000 的值)。

我的意思是范围的层次结构在这里看起来如何?

是这样的吗?

         controller's scope
                |
       +--------+---------+
       |                  |
  myTabs's             mypanes's
 transcluded           transcluded 
 data's scope          data's scope         

文档说:

transclude 选项改变了范围嵌套的方式。它使它 以便嵌入指令的内容具有任何范围 在指令之外,而不是内部的任何范围。在 这样做,它使内容可以访问外部范围。

但是myPAne 指令的外部有什么作用域?

换句话说,为什么/如何 i=1000

FULL PLUNKER

回答后从 OP 编辑​​

安装和配置 PeriScope(来自@MarkRajcok)后,我现在可以直观地看到它:

【问题讨论】:

  • myTab 和 myPane 都有 transclude: true。 myPane 嵌套在 myTab 中。您给 myPane 提供了 myTab 的范围,然后给 myTab 提供了 ctrl 的范围,这为 myPane 提供了 ctrl 的范围。

标签: angularjs angularjs-ng-transclude


【解决方案1】:

来自$compile上的文档

当你调用一个 transclude 函数时,它会返回一个 DOM 片段,它是 预先绑定到一个嵌入范围。这个范围很特别,因为它 是指令范围的子级(因此在 指令的范围被破坏)但它继承了 它的范围。

父级层次结构(来自 $$childTail)就像:

-1 (root)
--2 (ctrl)
---3 mytab
----4 ($$transcluded = true)
------5 mypane
--------6 ($$transcluded = true)

原型层次结构就像(来自 AngularJS Batarang 的屏幕截图)-

更新了plunker,并在控制台中打印了范围 ID,应该会给你一个更好的主意。

为什么这些不同,我不太确定。有人可以阐明这一点。

为什么值为 1000。这是因为 i 需要作为 双向 属性 = 提供,以便子作用域可以修改它。我已经更新了上面的 plunker,你现在可以看到 pane 控制器中的值响应变化。

关于嵌入范围的更多信息 -
Confused about Angularjs transcluded and isolate scopes & bindings
https://github.com/angular/angular.js/wiki/Understanding-Scopes

【讨论】:

  • 为什么将 i 添加到隔离作用域?我的问题没有。另外 - 在你的 plunker 中 - 你能解释一下什么是“mypane parent 4”吗?我知道 mytabs 和 mypane 都有隔离(不同)范围。但是mypane parent 4 是什么? mypane 的父级是什么?
  • 内嵌作用域是一种特殊作用域。在上面的例子中 - mypane parent 4 是嵌入的范围。我已经用一个解释嵌入范围的链接更新了帖子。
  • 但是我的问题有 2 个嵌入项,那为什么我只看到第 4 个?
  • 对。实际上还有第 6 个作用域。我已经更新了帖子。 2 个用于指令,2 个用于嵌入,rootscope 和 ctrl。
猜你喜欢
  • 2016-02-26
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 2011-01-01
  • 2010-12-18
  • 2018-05-23
  • 1970-01-01
相关资源
最近更新 更多