Search code examples
javascriptangularjsangularjs-scopetransclusion

Transclusion and scopes in angular: Why is this not working?


I have a very simple setup:

<pane title="mytitle">Title in parent (transcluded): {{title}}</pane>

and

angular.module('transclude', [])
 .directive('pane', function(){
    return {
      restrict: 'E',
      transclude: true,
      scope: { title:'@' },
      template: '<div>' +
                  '<div>Title in isolated scope: {{title}}</div>' +
                  '<div ng-transclude></div>' +
                '</div>'
    };
});

The plunker is here: http://plnkr.co/edit/yRHcNGjQAq1NHDTuwXku

The transclusion itself is working but the {{title}} only gets replaced in the directive's template.
The {{title}} inside the transcluded element however stays empty even though the directive has a variable title in its scope. Why is that?


Solution

  • The scope of the transcluded element is not a child scope of the directive but a sibling one. This is what documentation says:

    In a typical setup the widget creates an isolate scope, but the transclusion is not a child, but a sibling of the isolate scope.

    The simplest solution in this case how you can access transcuded scope is like this:

    .directive('pane', function () {
        return {
            restrict: 'E',
            transclude: true,
            scope: {
                title: '@'
            },
            template:
                '<div>' +
                    '<div>Title in isolated scope: {{title}}</div>' +
                    '<div ng-transclude></div>' +
                '</div>',
            link: function (scope, element, attrs) {
                scope.$$nextSibling.title = attrs.title;
            }
        };
    });
    

    Demo: http://plnkr.co/edit/ouq9B4F2qFPh557708Q1?p=preview