0

I have a simple scenario

<thead grid-columns pager-info="pagerInfo" onsort="onSort()">
    <tr>
        <th width="15%"><column sortby='FName'>Name</column></th>
        <th width="17%"><column sortby='Mobile'>Number</column></th>
    </tr>
</thead>

The idea is that since ALL my columns need an onsort defined, I can just define it once on the parent.

But, why doesn't my child directive (column) have it's $parent set to the grid-columns directive? Instead, scope.$parent is set to the controller scope, so I can't work out how to access my parent directive scope from my child directive.

Both of the directives have an isolated scope, and my child directive transcludes:

ngApp.directive('gridColumns', function () {
    // Attribute-based wrapper round the columns that allows us to capture the pagerInfo and set a sort handler.
    return {
        restrict: 'A',
        scope: {
            pagerInfo: '=',
            onsort: '='
        }
    };
});

ngApp.directive('column', function () {
    return {
        restrict: 'E',
        transclude: true,
        replace: true,
        scope: {
            sortby: '@'
        },
        template: "<span><a ng-click='sort()' ... </span>",
        link: function (scope, el, attrs) {
            scope.sort = function () {

                // I want to call scope.$parent.onsort, but scope.$parent is the controller !

                // scope.$parent.onsort(scope.sortby);
            };
        }
    };

});
Matt Roberts
  • 26,371
  • 31
  • 103
  • 180
  • Can you check this url @ http://stackoverflow.com/questions/20212354/angularjs-accessing-parent-directive-properties-from-child-directives – JQuery Guru Jan 31 '14 at 10:29

1 Answers1

1

You could try require:

ngApp.directive('column', function () {
    return {
        restrict: 'E',
        transclude: true,
        replace: true,
        scope: {
            sortby: '@'
        },
        template: "<span><a ng-click='sort()' ... </span>",
        require:"^gridColumns",
        link: function (scope, el, attrs,gridColumnsController) {//inject gridColumnsController
            scope.sort = function () {
                 gridColumnsController.onsort(scope.sortby);//call the controller's onsort function.
            };
        }
    };

});

Update your gridColumns to expose onsort:

ngApp.directive('gridColumns', function () {

    return {
        restrict: 'A',
        scope: {
            pagerInfo: '=',
            onsort: '&' //also update the function binding
        },
        controller:function($scope){
           this.onsort = function (sortBy){
                $scope.onsort({param:sortBy});
           }
        }
    };
});

Your HTML:

<thead grid-columns pager-info="pagerInfo" onsort="onSort(param)">

You could have more information at this: AngularJS - $emit only works within it's current scope?

Community
  • 1
  • 1
Khanh TO
  • 48,509
  • 13
  • 99
  • 115
  • Nice, never come across that before. For anyone else, it's documented quite well here: http://docs.angularjs.org/guide/directive – Matt Roberts Jan 31 '14 at 10:06
  • @Matt Roberts: I'm not sure if I understand you correctly, but I think you need to change your function binding to make it work. – Khanh TO Jan 31 '14 at 10:11
  • Thanks, I'd snipped some of the code out of the function to avoid posting too much code-noise, so yeah as it is it wouldn't work :) – Matt Roberts Jan 31 '14 at 11:02