MikeC
MikeC

Reputation: 284

AngularJS : tree directive not working properly

Creating an angular tree directive with an isolated scope that binds the value of two attributes...items and item-click-handler. Here is the code:

HTML

<div ng-app="myapp">
<div ng-controller="TreeCtrl">
    <item-tree class="tree" items="treeFamily" item-click-handler="groupSelectedFunction(itemId)"></item-tree>
</div>

JAVASCRIPT

var module = angular.module('myapp', []);

module.controller("TreeCtrl", function($scope) {
    $scope.treeFamily = [{
        Name : "Parent",
        Code : "Parent",
        Children: [{
            Name : "Child1",
            Code : "Child1",
            Children: [{
                Name : "Grandchild1",
                Code : "Grandchild1",
                Children: []
            },{
                Name : "Grandchild2",
                Code : "Grandchild2",
                Children: []
            },{
                Name : "Grandchild3",
                Code : "Grandchild3",
                Children: []
            }]
        }, {
            Name: "Child2",
            Code : "Child2",
            Children: []
        }]
    }];
    $scope.groupSelectedFunction = function (itemId) {
                alert(itemId + ' selected');
    }
});

module.directive("itemTree", function($compile) {
    return {
        restrict: "E",
        scope: {
            items: '=',
            itemClickHandler: '&'
        },
        template: 
            '<ul id="group-nodes" ng-repeat="item in items">' +                
                '<li id={{ item.Code }}>' + 
                    '<a ng-click="itemClickHandler({itemId: 1})">{{ item.Name }}</a>'+
                    '<item-tree items="item.Children" item-click-handler="itemClickHandler(itemId)"></item-tree>' +
                '</li>' +
            '</ul>',
        compile: function(tElement, tAttr) {
            var contents = tElement.contents().remove();
            var compiledContents;
            return function(scope, iElement, iAttr) {
                if(!compiledContents) {
                    compiledContents = $compile(contents);
                }
                compiledContents(scope, function(clone, scope) {
                         iElement.append(clone); 
                });
            };
        }
    };
});

The tree builds fine. If i click the top level parent node the controller function runs and shows an alert with the expected value: "Parent selected". However if any of the other nodes are clicked the the function runs but the alert message is: "undefined selected". Relatively new to Angular so this one has left me scratching my head. Would appreciate any help.

Upvotes: 0

Views: 274

Answers (1)

Marc Kline
Marc Kline

Reputation: 9409

It's not clear what ID should be showing in the alert for each child node, but it is more obvious why you're seeing undefined instead of a value...

When using the & isolate scope type, the arguments passed to a function from a template need to be passed in an object, which you followed for the top level element:

ng-click="itemClickHandler({itemId: 1})"

You need to follow the same syntax for the children. So,

item-click-handler="itemClickHandler(itemId)"

should be

item-click-handler="itemClickHandler({itemId: itemId})"

Demo

Upvotes: 2

Related Questions