Angular: функция обратного вызова Bind с использованием аргументов & и pass-in

У меня есть (упрощенная) директива

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

Теперь в каком-то родительском контроллере я определил функцию обратного вызова:

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

и HTML:

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

(Я использую такие вещи, как bindToController и controllerAs)

Проблема в том, что $event никогда не передается myCallback, что, скорее всего, связано с тем, как я привязываю эту функцию (&). Но, с другой стороны, внутри myCallback я хотел бы использовать this.

Есть ли способ исправить это? не делая таких вещей, как

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

Ответ 1

Вы не полностью настроили свои привязки правильно. Вы можете передать аргументы из директивы родительскому контроллеру с помощью карты значений ключа. Согласно angular docs (внимание мое):

& или &attr - обеспечивает способ выполнения выражения в контексте родительской области. Если имя attr не указано, предполагается, что имя атрибута совпадает с локальным именем. Учитывая <widget my-attr="count = count + value"> и определение виджета scope: { localFn:'&myAttr'}, затем изолировать свойство scope localFn будет указывать на оболочку функции для выражения count = count + value. Часто желательно передавать данные из изолированной области с помощью выражения в родительскую область, это можно сделать, передав карту локальных имен переменных и значений в оболочку выражения fn. Например, если выражение increment(amount), то мы можем указать значение суммы, вызывая localFn как localFn({amount: 22}).

Таким образом, в вашем потребляющем HTML вам нужно добавить параметры:

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

А затем в директиве:

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

Ответ 2

По моему мнению, вы должны сделать это следующим образом:

На странице HTML:

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

В вашей директиве:

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});
    }   
}

Но я не знаю, в чем суть вашего вопроса.