Question

I cannot make nested transclusion work.

There are two directives, both of which declare they will transclude their content. When I nest them, the inner doesn't have any content.

Here is this fiddle, that demonstrates my problem.

Here is the code:

function Ctrl($scope) {
  $scope.text = 'Neque porro quisquam est qui dolorem ipsum quia dolor...';
}

angular.module('transclude', [])
 .directive('outer', function(){
    return {
      restrict: 'E',
      replace: true,
      transclude: true,
      scope: {},
      template: '<div style="border: 1px solid black;">' +
                '<div>Outer</div>' +
                '<inner ng-transclude></inner>' +
                '</div>'
    };
 }).directive('inner', function(){
     return {
         restrict: 'E',
         transclude: true,
         replace: true,
         template :'<div style="border: 1px solid red;">' +
                   '<div>Inner</div>' +
                   '<div ng-transclude></div>' +
                   '</div>'
     };
 });
Was it helpful?

Solution

You should ng-transculde inside the inner directive since transclude replaces the inner html

angular.module('transclude', []).directive('outer', function(){
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        template: '<div style="border: 1px solid black;">' +
            '<div>Outer</div>' +
            '<inner><div ng-transclude></div></inner>' +
            '</div>'
        };
});

No change to inner directive needed.

I have updated the fiddle here

OTHER TIPS

Another way to do this, which can be useful in self contained components is displayed in this JSFiddle

.directive('outer', function(){
    return {
      restrict: 'E',
      replace: true,
      transclude: true,
      template: '<div style="border: 1px solid black;">' +
                '<div>Outer</div>' +
                '<inner></inner>' +
                '</div>'
    };
 })
.directive('inner', function(){
     return {
         restrict: 'E',
         replace: true,
         require: '^outer',
         template :'<div style="border: 1px solid red;">' +
                   '<div>Inner</div>' +
                   '<div ng-transclude></div>' +
                   '</div>'
     };
 });

This will pass the transclude: true down the dom tree to the inner directive.

The downside of this is that the cannot be used by itself and in the jsfiddle it throws an ngTransclude: Orphan Directive Error

Because of this I require that the inner directive be a child of the outer directive, that way it will always have the transclusion passed down to it.

This is really nice to break up large directives into smaller ones.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top