1

I want to make a categories tree with checkboxs (which is a recusive list) directive.

I did a directive called categoriesTreeContainer that containes all the list of categories

and I did another directive called categoryItem that containes the category item which is the child of categoriesTreeContainer

this is what I did categoriesTreeContainer:

myApp.directive('categoriesTreeContainer', function(){
return {
    restrict : 'E',
    template : '<category-item ng-repeat="category in categoriesTree" category="category"></category-item>',
    scope    : {
        categoriesTree : "=categoriestree",
        selectedCategories : "=ngModel",
    },

    controller : function($scope, $element, $attrs){
        $scope.selectedCategories = [];

        $scope.onSelectionChange = function(category){
            console.log('yah');
        }
    }
}

})

for the categoryItem:

myApp.directive('categoryItem', function($compile){
return {
    require: '^categoriesTreeContainer',
    restrict : 'E',
    //replace  : true,
    transclude : true,
    scope    : {
        category : "=category"
    },
    link     : function(scope, element, attrs, categoriesTreeCtrl){
        console.log(categoriesTreeCtrl);

        if(scope.category.subCategories.length>0){

            element.append($compile(
                '<div class="panel panel-default panel-treelist">'+
                '<div class="panel-heading"><h4 class="panel-title">'+
                '<label data-toggle="collapse" data-target="#{{category.$$hashKey}}">'+
                '<input type="checkbox" ng-change="categoriesTreeCtrl.onSelectionChange(category)"  ng-model="category.selected" />'+
                ' {{category.name}}</label></h4></div><div id="{{category.$$hashKey}}" class="panel-collapse collapse">'+
                '<div class="panel-body">'+
                '<category-item id="{{category.$$hashKey}}" ng-repeat="subCategory in category.subCategories" category="subCategory" categoriestree="categoriesTree" ng-model="selectedCategories">'+
                '</category-item></div></div></div>'
                )(scope))
        }else{
            element.append($compile('<label><input ng-change="categoriesTreeCtrl.onSelectionChange(category)" type="checkbox" ng-model="category.selected"> {{category.name}}</label><br/>')(scope));
        }
    }
}

})

and in the DOM:

<categories-tree-container categoriestree="categoriesTree" ng-model="selectedCategories"></categories-tree-container>

The tree is rendered as I wanted. The problem is that the required controller '^categoriesTreeContainer' in the categoryItem directive is void. I did a console.log(categoriesTreeCtrl) for the categoriesTreeCtrl in the link function and this what is what I get:

c {}, A void object.

What am I doing wrong?

mjhm
  • 16,497
  • 10
  • 44
  • 55
Sn0opr
  • 1,016
  • 2
  • 12
  • 38

1 Answers1

6

The categoriesTreeCtrl will be void object because the controller has nothing. If you need to access categoriesTreeCtrl.onSelectionChange from child directive, you should not put the onSelectionChange as part of it's $scope, but define it as the controller's property.

controller: function($scope, $element, $attrs){
      this.onSelectionChange = function(category){ ... };
 // $scope.onSelectionChange = function(category){...}
}

Additional :
the categoriesTreeCtrl on the child directive is not equal to $scope.categoriesTreeCtrl, which means, you can't call categoriesTreeCtrl from you template. Look at the ng-change value.

Iqbal Fauzi
  • 1,561
  • 11
  • 12