Search code examples
angularjsangularjs-directiveangular-directiveusing-directives

How pass function inside directive to another directive


I have two separated directives. If some condition is evaluated to true I have to call second directive inside first.

myDirectives.directive('first', function() {
  return {
    restrict: "E",
    templateUrl: "Views/_first.html",
    require: "ngModel",
    scope: {
      functiontocall: "&",
    }
  }
});

In HTML I'm calling directive as following:

<first ng-model="model.FirstDTO" 
       functiontocall="someFunctionForAsyncData(val)"></first>

Second directive is same, just with different html and passed function. I've omit additional data passed to directive which is not important for my current problem.

Now, I must call second directive inside first, so I've added additional function which is passed to first directive:

myDirectives.directive('first', function() {
  return {
    restrict: "E",
    templateUrl: "Views/_first.html",
    require: "ngModel",
    scope: {
      functiontocall: "&",
      functionforseconddirective: "&"
    }
  }
});

How can I, inside my first directive make something like this bellow, pass function that is passed to first directive to another one (it's not working now):

<second ng-model="secondModel" 
        secondFn="functionforseconddirective(val)"></second>

Just to state that this is special case where these two directive are nested, I have couple of places inside code where I call each of them separately, so I would like solution to this specific situation, but not affecting all normal places in code where both of them are working correctly.

Update: jsfiddler: http://jsfiddle.net/kujg10fL/1/ I would like that click on second button display expected msg


Solution

  • Well. you did now show enough information to create a full qualified answer. I think functionforseconddirective() is defined in your controller. In that way you don't need to parse this funtion from one directive to another. You need a trigger and you need to parse the value from on directive to enougher like in this demo fiddle.

    View

    <div ng-controller="MyCtrl">
      <input href="javascript:void(0);" 
             my-directive trigger="trigger" 
             my-value="someValue" />
    
      <div my-other-directive 
           fn="myTriggerFunction" 
           my-value="someValue" 
           trigger="trigger"></div>
    </div>
    

    AngularJS application

    var myApp = angular.module('myApp',[]);
    
    myApp.controller('MyCtrl', function ($scope) {
    
        $scope.trigger = false;
        $scope.someValue = '';
    
        $scope.myTriggerFunction = function (value) {
          console.log(value);
        };
    });
    
    myApp.directive('myDirective', function () {
        return {
          restrit: 'A',
          scope: {
            trigger: "=",
            myValue: "="
          },
          link: function (scope, element, attrs) {
              element.on('keyup', function () {
                scope.myValue = 'hello world';
                scope.trigger = true;
                scope.$apply();
              });
          }
        }
    });
    
    myApp.directive('myOtherDirective', function () {
        return {
          restrit: 'A',
          scope: {
            trigger: "=",
            myValue: "=",
            fn: "="
          },
          link: function (scope, element, attrs) {
              scope.$watch('trigger', function (newValue, oldValue) {
    
                if (newValue) {
    
                  //call controller function
                  scope.fn(scope.myValue);
    
                  //unset trigger
                  scope.trigger = false;
                  scope.$emit();
                }
              });
          }
        }
    });
    

    Updated answer based on your fiddle

    Please check this demo fiddle.

    View

    <div ng-app="dr" ng-controller="testCtrl">
        <test firstfn="someFn"></test>   
    </div>
    

    AngularJS application

    var app = angular.module('dr', []);
    app.controller("testCtrl", function($scope) {
        $scope.someFn = function(msg) {        
            alert(msg.msg);
        }
    });
    app.directive('test', function() {
        return {
            restrict: 'E',
            scope: {
                firstfn: '='
            },
            template: "<div><button ng-click='firstfn({msg:\"Hello World!\"})'>Click</button><br /> <testinner secondfn='firstfn'></testinner> </div>",
            replace: true,        
            link: function(scope, elm, attrs) {     
               console.log(scope.firstfn);
            }
        }
    });
    app.directive('testinner', function() {
        return {
            restrict: 'E',
            scope: {
                secondfn: '='
            },
            template: "<div>second directive<button ng-click='secondfn({msg:\"Hello World from another!\"})'>Click</button></div>",
            replace: true,        
            link: function(scope, elm, attrs) {             
            }
        }
    });