Angular: calling controller function inside a directive link function using &

80,377

Solution 1

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.

Solution 2

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);
    }
}
Share:
80,377
Walt
Author by

Walt

Updated on July 08, 2022

Comments

  • Walt
    Walt almost 2 years

    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
    Walt about 11 years
    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.
  • Nicholas Dynan
    Nicholas Dynan over 9 years
    thank you soooo much, was struggling with this. Know how to pass the object map on an ng-click but this is awesome.
  • Vinicius.Silva
    Vinicius.Silva about 8 years
    scope.someCtrlFn({arg1: 22}); is that i looking for! Thank you a lot!!
  • Ashit Vora
    Ashit Vora over 7 years
    what happens if argument passed in directive is an object property. Eg. <div my-directive callback-fn="ctrlFn(x.y.z, arg2)" />
  • James Drinkard
    James Drinkard over 7 years
    I finally found this syntax in the Angularjs docs. I think it was unintentionally well hidden. Thanks for posting this Mark!
  • trainoasis
    trainoasis over 6 years
    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 ...