Прослушать несколько событий в $scope
У меня есть директива, которая связывает некоторые функции с локальной областью с $scope.$on
.
Можно ли связать одну и ту же функцию с несколькими событиями в одном вызове?
В идеале я мог бы сделать что-то вроде этого:
app.directive('multipleSadness', function() {
return {
restrict: 'C',
link: function(scope, elem, attrs) {
scope.$on('event:auth-loginRequired event:auth-loginSuccessful', function() {
console.log('The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks');
});
}
};
});
Но это не работает. Тот же пример с строкой имени события, разделенной запятой, замененным на ['event:auth-loginRequired', 'event:auth-loginConfirmed']
, также не работает.
Что это за работа:
app.directive('multipleSadness', function() {
return {
restrict: 'C',
link: function(scope, elem, attrs) {
scope.$on('event:auth-loginRequired', function() {
console.log('The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks');
});
scope.$on('event:auth-loginConfirmed', function() {
console.log('The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks');
});
}
};
});
Но это не идеально.
Возможно ли связать несколько событий с одной и той же функцией за один раз?
Ответы
Ответ 1
Да. Вот так:
app.directive('multipleSadness', function() {
return {
restrict: 'C',
link: function(scope, elem, attrs) {
function sameFunction(eventId) {
console.log('Event: ' + eventId + '. The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks.');
}
scope.$on('event:auth-loginRequired', function() {sameFunction('auth-loginRequired');});
scope.$on('event:auth-loginConfirmed', function () {sameFunction('auth-loginConfirmed');});
}
};
});
Но только потому, что вы можете, это не значит, что вы должны:). Если события продолжают распространяться до другого слушателя, и они обрабатываются по-другому, возможно, есть случай сделать это. Если это будет единственный слушатель, вы должны просто выпустить (или передать) одно и то же событие.
Ответ 2
Другие ответы (Anders Ekdahl) на 100% правильны... выберите один из них... НО...
Запрет на то, что вы всегда можете сделать свой собственный:
// a hack to extend the $rootScope
app.run(function($rootScope) {
$rootScope.$onMany = function(events, fn) {
for(var i = 0; i < events.length; i++) {
this.$on(events[i], fn);
}
}
});
app.directive('multipleSadness', function() {
return {
restrict: 'C',
link: function(scope, elem, attrs) {
scope.$onMany(['event:auth-loginRequired', 'event:auth-loginSuccessful'], function() {
console.log('The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks');
});
}
};
});
Я предполагаю, что если вы действительно хотели сделать .split(',')
, вы могли бы, но это была деталь реализации.
Ответ 3
AngularJS не поддерживает множественную привязку событий, но вы можете сделать что-то вроде этого:
var handler = function () { ... }
angular.forEach("event:auth-loginRequired event:auth-loginConfirmed".split(" "), function (event) {
scope.$on(event, handler);
});
Ответ 4
Я не думаю, что это возможно, поскольку событие может отправлять данные в обратный вызов, и если вы слушаете несколько событий, вы не знаете, какие данные пришли из какого-либо события.
Я бы сделал что-то вроде этого:
function listener() {
console.log('event fired');
}
scope.$on('event:auth-loginRequired', listener);
scope.$on('event:auth-loginConfirmed', listener);
Ответ 5
Также как с $rootScope. $onMany (решение от @ben-lesh) можно расширить метод $on:
var $onOrigin = $rootScope.$on;
$rootScope.$on = function(names, listener) {
var self = this;
if (!angular.isArray(names)) {
names = [names];
}
names.forEach(function(name) {
$onOrigin.call(self, name, listener);
});
};
взял здесь.