I need help with a treeview directive in my project. I am having trouble invoking a function from the parent controller and can't seem to figure out why it's not working. It could be due to the structure of the treeview and nesting of child elements.
In my HTML, I have declared the directive as:
<div ng-controller="treeController as vm">
<tree src="myList" filter="doSomething()"></tree>
<a ng-click="clicked()"> link</a>
</div>
I have defined an attribute/parameter filter
in the directive that should call the doSomething()
function in the main controller.
The main controller code includes:
app.controller("treeController", ['$scope', function($scope) {
var vm = this;
$scope.doSomething = function () {
var item = data;
}
$scope.clicked = function () {
alert('clicked');
}
$scope.myList = {
children: [
{
name: "Event",
children: [
{
name: "Event Date",
children: [
{
name: "2008",
FilterType: '_eventStartDate',
Parent: '_event'
},
{
name: "2009",
FilterType: '_eventStartDate',
Parent: '_event'
}
]
},
{
name: "Event Attendee",
children: [
{
name: "Person 1",
FilterType: '_eventAttenddeeName',
Parent: '_Event'
},
{
name: "Person 2",
FilterType: '_eventAttenddeeName',
Parent: '_Event'
}
]
}
]
}]
};
}]);
In the directive, I declare the isolated scope and the parameter filter
using model binding prefix '&'
. I then use ng-click within the template to invoke the doSomething()
function in the main controller. However, the function is not being called.
app.directive('tree', function() {
//builds the tree
return {
restrict: 'E',
replace: true,
scope: {
t: '=src'
},
template: '<ul><branch ng-repeat="c in t.children" src="c"></branch></ul>'
};
});
app.directive('branch', function($compile) {
//directive that builds the children/branches
return {
restrict: 'E',
replace: true,
scope: {
b: '=src',
filter: '&'
},
template: '<li><input type="checkbox" ng-click="filter()" ng-hide="visible" /><a>{{ b.name }}</a></li>',
link: function (scope, element, attrs) {
var has_children = angular.isArray(scope.b.children);
scope.visible = has_children;
if (has_children) {
element.append('<tree src="b"></tree>');
$compile(element.contents())(scope);
}
element.on('click', function(event) {
event.stopPropagation();
if (has_children) {
element.toggleClass('collapsed');
}
});
//test to call function within directive
//scope.doSomething = function(b) {
// alert('test');
//}
}
};
});
A demo of the code sample can be found on jsFiddle.
If you have any suggestions or solutions to why the function in my controller is not getting called, please let me know.
Currently, I am focused on invoking the method, but eventually, I will need to pass the selected item back to the controller as well.
Update: It was recommended to move the declaration of the filter from the branch to the tree directive.
I made changes locally to the tree directive as follows:
app.directive('tree', function() {
return {
restrict: 'E',
replace: true,
scope: {
t: '=src',
filter: '&'
},
template: '<ul><branch ng-repeat="c in t.children" src="c"></branch></ul>'
};
});
Note: the filter parameter was removed from the secondary directive, but there was no change in the output. The function in the controller still wasn't being called.