Angular: Bind callback function using & and pass-in arguments

22,640

Solution 1

You haven't completely set up your bindings correctly. You can pass back arguments from the directive to the parent controller via a key-value map. According to the angular docs (emphasis mine):

& or &attr - provides a way to execute an expression in the context of the parent scope. If no attr name is specified then the attribute name is assumed to be the same as the local name. Given <widget my-attr="count = count + value"> and widget definition of scope: { localFn:'&myAttr'}, then isolate scope property localFn will point to a function wrapper for the count = count + value expression. Often it's desirable to pass data from the isolated scope via an expression to the parent scope, this can be done by passing a map of local variable names and values into the expression wrapper fn. For example, if the expression is increment(amount) then we can specify the amount value by calling the localFn as localFn({amount: 22}).

So that means in your consuming HTML you need to add parameters:

<my-button callback-fn="page.myCallback(parentEvent)"></my-button>

And then in the directive:

......
restrict: 'E',
scope: {
            callbackFn: '&'
       },
template: '<button ng-click="ctrl.callbackFn({parentEvent: $event})">Callback</button>'

,

Solution 2

According to me you should do it this way :

In your HTML page :

<my-button callback-fn="page.myCallback(event)"></my-button>

In your directive :

angular.module('myApp')
    .directive('myButton', function () {
        return {
            restrict: 'E',
            controller: 'Controller',
            bindToController: true,
            scope: {
                callbackFn: '&'
            },
            template: '<button ng-click=foo($event)'
        }
});

function Controller() {
    this.foo = function (event) {
        this.callbackFn({event: event});
    }   
}

But I'm not sur what's the point of your question.

Share:
22,640
Jeanluca Scaljeri
Author by

Jeanluca Scaljeri

Updated on July 09, 2022

Comments

  • Jeanluca Scaljeri
    Jeanluca Scaljeri almost 2 years

    I have a (simplified) directive

    angular.module('myApp')
       .directive('myButton', function () {
            return {
                restrict: 'E',
                scope: {
                    callbackFn: '&'
                },
                template: '<button ng-click=ca;;backFn($evenb)'
            }
       });
    

    Now, in some parent controller I have defined a callback function:

    this.myCallback = function ($event) {
        this.doIt($event);
    }
    

    and the HTML:

    <my-button callback-fn="page.myCallback()"></my-button>
    

    (I'm using things like bindToController and controllerAs)

    The issue is that the $event is never passed to myCallback, which most likely has to do with how I bind this function (&). But on the other hand, inside myCallback I would like to use this.

    Is there some way to fix this ? without doing things like

    var self = this;
    this.myCallback = function ($event) {
         self.doIt($event);
    }
    
  • Peter Nixey
    Peter Nixey over 6 years
    thank you! Struggled for ages with this. Great explanation