Reputation: 284
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
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})"
Upvotes: 2