6

I already know how transclusion works ( within first level only I guess) , bUt I have a question about nested transcluded item's scope.

Ok so I have this code :

<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>

Basically I have a controller , <my-tabs> and <my-pane >.

Looking at myTabs directive :

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

I know that the content of the directive will have access to the outer directive's scope

So the yellow part will have access to the outer scope ( which is the main controller scope) :

enter image description here

Here is the code for myPane directive :

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

The program starts with :

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

The output of the program is :

Hello , The value of "i" is => 1000

But

According to the documentation : myPane's transcluded data should have access to the outer scope of the directive which is myTabs directive which has the value i=2.

But myPane has an isolated scope so it does NOT inherit the scope from myTabs.

Question

So does it goes one level more higher to the controller's scope in order to get i=1000 ?? (Clarification , I'm not asking how can I make i get another value - I'm asking why/how it has the value of 1000).

I mean how does the hierarchy of scope looks here?

Is it like this?

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

the docs says :

The transclude option changes the way scopes are nested. It makes it so that the contents of a transcluded directive have whatever scope is outside the directive, rather than whatever scope is on the inside. In doing so, it gives the contents access to the outside scope.

But what scope does the outside of myPAne directive has ?

In other words , why/how does i=1000?

FULL PLUNKER

EDIT FROM OP AFTER ANSWER

After installing and configuring PeriScope ( from @MarkRajcok) I can now see it visually :

enter image description here

4

1 回答 1

1

来自$compile上的文档

当你调用一个 transclude 函数时,它会返回一个预先绑定到一个 transclusion 范围的 DOM 片段。这个作用域是特殊的,因为它是指令作用域的一个子对象(因此当指令的作用域被破坏时也会被破坏),但它继承了它所在作用域的属性。

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

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

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

ng-transclude 原型层次结构

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

为什么这些不同,我不太确定。有人可以对此有所了解。

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

更多关于嵌入范围 -
对 Angularjs 嵌入和隔离范围和绑定感到困惑
https://github.com/angular/angular.js/wiki/Understanding-Scopes

于 2015-12-08T18:32:30.453 回答