AngularJS, передача аргументов из директивы в контроллер

При написании своих директив в AngularJS легко столкнуться с необходимостью вызвать из директивы функцию контроллера, передав аргументом что-нибудь из scope директивы. Например, если директива представляет собой форму для создания новых элементов — мы можем передать в контроллер введенные пользователем, обработанные и отвалидированные значения.

Пусть у нас в контроллере есть функция:

$scope.alertNewItem = function (item) {
  alert(item.title);
  alert(item.value);
};

Тогда эту функцию мы можем передать в scope директивы, скажем, в атрибуте on-save:

angular.module('myModule').directive('addNewItem', function () {
  return {
    restrict: 'E',
    templateUrl: 'item-add-tpl.html',
    replace: true,
    link: addNewItemLink,
    scope: {
      //коллбэк добавления нового элемента
      saveCallback: '&onSave'
    }
  };
});

Примерно так:

<add-new-item on-save="alertNewItem(item)"></add-new-item>

Теперь мы можем вызвать эту функцию где-нибудь в link-функции нашей директивы:

function addNewItemLink(scope, element) {
  //...
  var myNewItem= {title: 'Новый элемент', value: 1};
  scope.saveCallback(myNewItem);
  //...
};

Однако если мы попробуем обратиться к аргументу item в функции alertNewItem() нашего контроллера, то увидим, что он undefined. Если внимательно (очень внимательно) читать документацию на directive(), можно выяснить, что, оказывается, аргументом в такие коллбэки нужно передавать не сами переменные, а карту (т.е. map) отображения передаваемых аргументов на их названия в вызываемой функции. То есть вот так:

function addNewItemLink(scope, element) {
  //...
  var myNewItem = {title: 'Новый элемент', value: 1};
  scope.saveCallback({item: myNewItem});
  //...
};

Комментарии