Вопрос

There are two directives collection and element, both of them transclude it's content, both of them have scope: false (default value).

This directives are used as wrapper on some container and wrapper on some items in that container, and used as follows:

<body ng-app="myApp" ng-controller="MyController">
 <collection>
    <element>inner1</element>
    <element>inner2</element>
    <element>inner3</element>
  </collection>
</body>

This directives are defined like this:

angular.module('myApp', [])
.controller('MyController', function($scope){
    console.log('MyController', $scope.$id);
})
.directive('collection', function($compile){
    return {
        transclude: 'true',
        restrict: 'E',
        template: '<header>header</header><div><ul ng-transclude></ul></div><footer>footer</footer>',
        link: function(scope){
            console.log('collection', scope.$id);
        }
    }
})
.directive('element', function(){
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        template: '<li><div ng-transclude></div></li>',
        link: function(scope){
            console.log('element', scope.$id);
        }
    }
});

The problem is that directive element is using not same scope as directive collection, and i can't figure out why.

console output

MyController 003
element 004
element 004
element 004
collection 003 

As you can see, MyController is sharing with collection same scope #3, but all element-s use scope #4.

Here is working example: plunkr

Это было полезно?

Решение

When you log scope.$id to console in the linking function, you're logging the scope id of the directive itself. However, when you use transclusion in a directive, a new scope is also created for the transcluded content.

enter image description here

This is fairly simple to understand once you see it. Things become a bit more interesting once you set isolate scope on a directive using transclusion.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top