0

I'm trying to implement nested directives. The inner directive is a button which calls a function in ng-click. The name of the function to be called is defined in the model.

To start off with, here is the plunker link. PLUNKER

The problem is that the button does not know the function to be called. Funnily enough, if I use a template for the outer directive using ng-include and variables rightly named in the scope, it works like a charm.

Some Code Snippets for you:

index.html:

DIRECTIVES
<outer-directive functions="functions" datas="datas"></outer-directive>

<p>{{clicked}}</p>

NG-Include :
<div ng-include src="'outer-template.html'"></div>

Template for outer directive

<div ng-repeat="d in datas">
  Hi, {{d}}
  <inner-directive 
    ng-repeat="funct in functions" 
    text="funct.text" 
    method="this[funct.method](d)">
  </inner-directive>
</div>

Controller

app.controller('MainCtrl', function($scope) {
  $scope.datas = [0, 1];
  $scope.functions = [{
    method: 'functOne',
    text: 'Funct One'
  }, {
    method: 'functTwo',
    text: 'Funct Two'
  }];


  $scope.clicked = 'Nothing happend';

  $scope.functOne = function(data) {
    $scope.clicked = data + ' pressed Funct 1';
  }

  $scope.functTwo = function(data) {
    $scope.clicked = data + ' pressed Funct 2';
  }

});

Outer Directive JS

app.directive('outerDirective', function() {
  return {
    restrict: 'E',
    scope: {
      functions: '=',
      datas: '='
    },
    templateUrl: 'outer-template.html'
  }
});

Inner Directive JS

app.directive('innerDirective', function() {
  return {
    restrict: 'E',
    scope: {
      method: '&',
      text: '=',
      datas: '='
    },
    template: '<button ng-click="method(datas)"> {{text}}</button>'
  }
});
  • So, I decided to go with $emit and $on (see [this question](https://stackoverflow.com/questions/14502006/working-with-scope-emit-and-scope-on)) – old_account Jul 19 '17 at 15:05

1 Answers1

0

In call back function from directive to controller the parameters should be passed as an object.

Here is the demo plunker click here

Hope it helps to understand how to pass param from directive to controller through call back function.

Now moving forward to nested directive : The same process need to be followed to pass parameter across directive and hence finally to controller.

Let the controller be

app.controller('MainCtrl', function($scope) {
  $scope.datas = [0, 1];

  $scope.functions = [{
    "method": "functOne",
    "text": "Funct One"
  }, {
    "method": "functTwo",
    "text": "Funct Two"
  }];

  $scope.clicked = 'Nothing happend';

  $scope.functOne = function(id){
   $scope.clicked = id + ' .....pressed Funct 1';
  }

  $scope.functTwo = function(id){
    $scope.clicked = id + ' ....pressed Funct 2';
  }

});

Outer diretive

app.directive('outerDirective', function() {
  return {
    restrict: 'E',
    scope: {
      outer: '&',
      datas: '='
    },
    templateUrl: 'outer-template.html',
  }
});

Inner directive

app.directive('innerDirective', function() {
  return {
    restrict: 'E',
    scope: {
      inner: '&',
      text: '=',
      data: '='
    },
    template: '<button ng-click="clickMe()">click here</button>',
    link: function (scope, element, attrs) {
        scope.clickMe=function(){

          scope.inner({id:'hello... data is ' + scope.data });
        }
  }

  }
});

HTML

<body ng-controller="MainCtrl">

    <div ng-repeat="func in functions">
      <outer-directive outer=$eval(func.method)(term) datas="datas"></outer-
       directive>
    </div>

    <p>{{clicked}}</p>

  </body>

Template

<div ng-repeat="d in datas">
<inner-directive inner="outer({term: id})" data="d"></inner-directive>
</div>

Here is the working plunker

himanshu
  • 188
  • 2
  • 16
  • Thanks for the detailed answer. In my case, I need the functions to repeat within the outer directive, and not letting the outer directives repeat for each function. So I cannot bind each function with '&' in the outer directive. – old_account Jul 13 '17 at 13:00