Search code examples
javascriptangularjsangularjs-directiveangularjs-scope

Angular JS - using ControllerAs with nested custom directives


As the title suggests I'm having a few issues on a Angular project which uses nested custom directives. I am creating an interface which allows users to filter a JSON feed of search results by clicking on checkboxes. The directive template hierarchy is as follows:

<filtergroup>
    <filter></filter>
</filtergroup>

I seem to be able to access variables defined in the filtergroup directive's controller within the template for the filtergroup. However I can't access the same variables from within the child directive, despite using

require: '^filtergroup'

Below are my directives:

.directive('filtergroup', [function(){
return{
    restrict: 'E',
    transclude: true,
    scope: { },
    template: '<div><ng-transclude></ng-transclude>{{filtergroup.variable}}</div>',
    bindToController: true,
    controllerAs: 'filtergroup',
    replace: true,
    controller: function() {
        var self = this;
           self.variable = "blah";
    }
};}])

.directive('filter', [function(){
return {
    restrict: 'E',
    template: '<div>{{filtergroup.variable}}</div>',
    require: '^filtergroup',
      scope: {},
    link: function(scope, elem, attr, filtergroupCtrl){
        scope.active = false;
    }
};}]);

I've also created a simplified Codepen of the issue at:

http://codepen.io/decodedcreative/pen/NrNqXm

Any help would be great as this is driving me crazy! Thanks


Solution

  • By saying require: '^filtergroup' you're only asking to inject the filtergroup's controller to the link function. Then it's up to you how to use it.

    In your case, you could add a filtergroupCtrl's reference to the filter's scope:

    .directive('filter', [function(){
        return {
            // ...
            template: '<div>{{filtergroup.variable}}</div>',
            link: function(scope, elem, attr, filtergroupCtrl){
                scope.filtergroup = filtergroupCtrl;
                // ...
            }
        };
    }]);
    

    This way you'll be able to access it in the child's template the way you're attempting to do it:

    <div>{{filtergroup.variable}}</div>