0

I have a directive which inherits its scope from a controller. This Directive has a few methods, when I try to call these methods from the Parent Controller it says method undefined.

Parent Controller:

app.controller('ParentController', ['$scope', function($scope){
    $scope.items = []; //Array of Objects.
    $scope.someMethod = function(item){
        $scope.directiveMethod(item.id);
    }
}]);

Directive:

app.directive('someDirective', function(){
    return {
        restrict: 'A',
        link: function(scope, el, attrs){
            scope.tableGreen = function(id){
               var element = angular.element('[data-cell='+id+']')
               element.removeClass('some-class')
               element.addClass('new-class')
           }
       }
   }
})

HTML:

<div ng-controller="ParentController">
    <div ng-repeat="item in items">
        <button ng-click="someMethod(item)" >Green</button>
    </div>

    <div ng-include="/path/to/some/place">
        <div class="some-class" some-directive></div>
    </div>
</div>

Is this a right approach? Or is there a better way?

Dwijen
  • 590
  • 4
  • 15
  • This is a very wrong approach. a directive could know the controller, but the controller should definitely not know the directive's model. that's against the whole concept of directives and encapsulation. – Daniel Jan 28 '16 at 15:31
  • please read this: http://stackoverflow.com/questions/17900201/how-to-access-parent-scope-from-within-a-custom-directive-with-own-scope-in-an – Ricardo Pontual Jan 28 '16 at 15:34
  • I think you use $broadcast or $emit for this work. it's work perfect for this condition – Sandeep Jan 28 '16 at 15:58
  • Why doesn't it work? Because ng-include creates a new scope. So the directive adds the function to the ngInclude scope, not to the controller scope. – JB Nizet Jan 28 '16 at 16:06

2 Answers2

0

If you are trying to toggle the class of an element triggered from outside of an ng-include one approach could be to utilize ng-class on the element itself:

<div ng-class="{'some-class': item.selected, 'new-class': !item.selected}">content</div> 

This could avoid doing the class manipulation via another function and utilize a built-in angular directive, ng-class (https://docs.angularjs.org/api/ng/directive/ngClass).

If you still need to attach other functionality to the element you can of course include ng-class within a directive template.

Take this plnkr for example: http://plnkr.co/edit/Jpr2ayywYYBwiIesmfko?p=preview, it has a set of items in a parent controller, then an ng-include that references those items. The class is changed on elements inside the ng-include from their directive templates with ng-class.

paul trone
  • 702
  • 5
  • 10
  • I thought about using `ng-class` at first, but I have the classes coming in an API response with some other data. That's why I need to do class manipulation from the directive. – Dwijen Jan 29 '16 at 09:04
  • Marking this as the correct answer because if you think hard enough you will find a way to do class manipulation with `ng-class`. – Dwijen Jan 29 '16 at 11:18
0

Assign the method to the $parent scope in the directive link.

app.directive('someDirective', function(){
    return {
        restrict: 'A',
        link: function(scope, el, attrs){
            scope.$parent.directiveMethod = function(id){
               var element = angular.element('[data-cell='+id+']')
               element.removeClass('some-class')
               element.addClass('new-class')
           }
       }
   }
})
brewsky
  • 607
  • 1
  • 9
  • 15