61

We're running into a problem trying to call a function passed into a directive using the ampersand '&' in our directive's link function.

It seems the function is called on the controller but no arguments are passed in the call. All the examples we have seen involve passing through by creating a call in template. Is there a way to call a function on your directive from its template, then do something in the directive that calls the controller function passed into it?

Walt
  • 1,521
  • 2
  • 13
  • 29
  • 1
    You can see this example http://stackoverflow.com/questions/16881478/how-to-call-a-method-defined-in-an-angularjs-directive – vmontanheiro Nov 07 '14 at 16:34

2 Answers2

159

Are you passing the arguments inside {}s? E.g., inside the directive's link function, you'll want to call the method like so: scope.someCtrlFn({arg1: someValue});

<div my-directive callback-fn="ctrlFn(arg1)"></div>
app.directive('myDirective', function() {
    return {
        scope: { someCtrlFn: '&callbackFn' },
        link: function(scope, element, attrs) {
            scope.someCtrlFn({arg1: 22});
        },
    }
});

function MyCtrl($scope) {
    $scope.ctrlFn = function(test) {
        console.log(test);
    }
}

Fiddle.

Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
  • 4
    Thanks! We just figured that out... didn't realize the key on the object had to match the argument function call that is passed in. – Walt May 30 '13 at 15:25
  • 1
    thank you soooo much, was struggling with this. Know how to pass the object map on an ng-click but this is awesome. –  Oct 31 '14 at 01:52
  • `scope.someCtrlFn({arg1: 22});` is that i looking for! Thank you a lot!! – Vinicius.Silva Apr 10 '16 at 22:50
  • what happens if argument passed in directive is an object property. Eg.
    – Ashit Vora Oct 16 '16 at 09:40
  • I finally found this syntax in the Angularjs docs. I think it was unintentionally well hidden. Thanks for posting this Mark! – James Drinkard Feb 13 '17 at 19:09
  • What if you don't want to force a directive user to use "arg1" exactly but whatever he wants, any dynamic variable/value? Not possible then? You are all passing variable (22) from inside directive - i want to pass it from controller, and it can be anything ... – trainoasis Jan 22 '18 at 09:43
31

In addition to Mark's answer I'd like to point out that you can spare some letters using the & shorthand. This will assume that the callback-fn referenced in your HTML exists as scope.callbackFn in your scope. Everthing else is still the same, so there are only 2 lines to change. I kept Mark's version as comments, so you should be able to spot the difference easily.

<div my-directive callback-fn="ctrlFn(arg1)"></div>
app.directive('myDirective', function() {
    return {
        scope: { callbackFn: '&' }, //scope: { someCtrlFn: '&callbackFn' },
        link: function(scope, element, attrs) {
            scope.callbackFn({arg1: 22}); //scope.someCtrlFn({arg1: 22});
        },
    }
});

function MyCtrl($scope) {
    $scope.ctrlFn = function(test) {
        console.log(test);
    }
}
robro
  • 1,730
  • 23
  • 26