Toby
Toby

Reputation: 1548

Repeating transcluded content in an angular directive

I'm trying to write a simple tree directive in Angular which will nest items, and repeat the transcluded content declared in the first call to the directive, in each of the repeated items.

I have tried this,

angular.module('angularTree',[])
    .directive('tree',['$compile',function($compile)
    {

        return {

            scope:{item:"="},
            transclude:true,
            template:"<div class='tree-item'><ng-transclude></ng-transclude>" +
                        "<div id='tree-content' class='tree-content'>" +
                            "<div ng-repeat='child in item.items'>" +
                                "<tree item='child'><ng-transclude></ng-transclude></tree>" +
                            "</div>" +
                        "</div>",
            link:function(scope,element,attrs)
            {

            }
        }


    }]);

And it works up to a point. It creates a nested tree, with the transcluded content.

The problem is that the scope in the repeated child directives, is always pointing at the very first item declared. So when I have a variable like this in my controller..

var item = {name:John, items:[{name:Tony},{name:Jill}]};

And pass it into the directive like this

<tree item="item"></tree>

I get a nested list of items, but they all say 'John'.

I can see why this happens, because the second is just going to have the same scope as the first..

My question is...how would I go about repeating the transcluded content in the child elements, but with the scope pointing to the child object not the top node?

I've read up on and tried using the $compile, and transclude functions, but I couldn't see any way to get this working.

Thanks

Upvotes: 1

Views: 384

Answers (1)

Stefan Negele
Stefan Negele

Reputation: 1112

It should be work like you have it. I think you´ve just mixed up item and child. Can´t be sure on that since your code doesn´t show where it outputs the names.

Inside the ng-repeat loop, child refers to the given of item.items, but item still is the same as the outer item. I´ve provided a working example, with the outputs in the comments:

angular.module('myApp', [])
.directive('tree',[function($compile) {
    return {
      scope:{
        item: "="
      },
      transclude:true,
      template: "{{item.name}}" + // John, Tony, Jill
                "<div class='tree-item'><ng-transclude></ng-transclude>" +
                  "<div id='tree-content' class='tree-content'>" +
                    "<div ng-repeat='child in item.items'>" +
                      "{{item.name}}" + // John, John
                      "{{child.name}}" + // Tony, Jill
                      "<tree item='child'><ng-transclude></ng-transclude></tree>" +
                    "</div>" +
                  "</div>",
      link: function(scope,element,attrs) {}
    }
  }]
)
.controller('treeCtrl', ['$scope', function($scope) {
  $scope.item = {
    name: 'John', 
    items: [
      {name: 'Tony'},
      {name: 'Jill'}
    ]
  };
}])

Upvotes: 1

Related Questions