Как вызвать функцию контекста родителя со смешанными аргументами?

Это мой случай - у меня есть директива с изолированной областью действия, и я хотел бы вызвать функцию из области действия родителя со смешанными аргументами. Смешанный - это означает, что один аргумент исходит из директивы, а другой - от родителя.

В случае аргументов, исходящих из директивы, я мог бы связать эту функцию с < и использовать его, в случае аргументов, приходящих из области видимости родителя, я мог бы связать весь вызов функции с &,

Я имею в виду два подхода - один, имитирующий каррирование, вызывающий функцию с аргументами родителя, которая возвращает функцию, принимающую директивные аргументы. Второе - как-то ввести директивные переменные в родительскую область видимости, чтобы я мог написать:

<my-directive on-alarm="emergency(parent_var,dir_var)"/>

Мне больше нравится второй. Но я не знаю, как это сделать, то есть, как ввести переменные директивы в родительскую область видимости - без ручного "обратного" связывания, например:

<my-directive for_sake_of_calling="dir_var" on-alarm="emergency(parent_var,dir_var)"/>

Но это больше похоже на мои догадки - главный вопрос: как вызвать функцию родителя со смешанными аргументами?

1 ответ

Решение

Вы можете достичь этого, выполнив следующие действия:

Сначала настройте основное приложение HTML,

<body ng-app="app">
    <div ng-controller="MainCtrl as vm">
        Emergency text: {{vm.emergencyText}}
        <my-directive on-alarm="vm.emergency(vm.parentVar, directiveVar)"></my-directive>
    </div>
</body>

Вы заметите, что on-alarm обратный вызов содержит ссылку на vm.parentVar переменная, которая просто относится к MainCtrl.parentVar, а также directiveVar который будет исходить из самой директивы.

Теперь мы можем создать наш главный контроллер:

angular.module('app', []);

angular
  .module('app')
  .controller('MainCtrl', function () {
    // Initialise the emergency text being used in the view.
    this.emergencyText = '';
    // Define our parent var, which is a parameter called to the emergency function.
    this.parentVar = 'This is an emergency';

    // Define the emergency function, which will take in the parent 
    // and directive text, as specified from the view call 
    // vm.emergency(vm.parentVar, directiveVar).
    this.emergency = function (parentText, directiveText) {
      this.emergencyText = parentText + ' ' + directiveText;
    }.bind(this);
  });

Наконец, мы создадим директиву.

angular
  .module('app')
  .directive('myDirective', function () {
    return {
      scope: {
        onAlarm: '&'
      },
      link: function (scope, element, attrs) {
        scope.onAlarm({ directiveVar: 'from myDirective' });
      }
    }
  });

Волшебство происходит после того, как мы позвоним scope.onAlarm({ directiveVar: 'from myDirective' });, Этот вызов сообщает Angular, что функция обратного вызова (экстренная) будет иметь доступ к directiveVar, на который мы ссылались ранее в представлении через on-alarm="vm.emergency(vm.parentVar, directiveVar)", За кулисами angular правильно разрешит область видимости parentVar в MainCtrl, а область directiveVar - в директиву через службу $ parse.

Вот полный планкр.

Другие вопросы по тегам