Как вызвать функцию контекста родителя со смешанными аргументами?
Это мой случай - у меня есть директива с изолированной областью действия, и я хотел бы вызвать функцию из области действия родителя со смешанными аргументами. Смешанный - это означает, что один аргумент исходит из директивы, а другой - от родителя.
В случае аргументов, исходящих из директивы, я мог бы связать эту функцию с <
и использовать его, в случае аргументов, приходящих из области видимости родителя, я мог бы связать весь вызов функции с &
,
Я имею в виду два подхода - один, имитирующий каррирование, вызывающий функцию с аргументами родителя, которая возвращает функцию, принимающую директивные аргументы. Второе - как-то ввести директивные переменные в родительскую область видимости, чтобы я мог написать:
<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.
Вот полный планкр.