J'ai une directive qui lie certaines fonctions à la portée locale avec $scope.$on
.
Est-il possible de lier la même fonction à plusieurs événements en un seul appel?
Idéalement, je serais capable de faire quelque chose comme ça:
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');
});
}
};
});
Mais ça ne marche pas. Le même exemple avec la chaîne de nom d'événement séparée par des virgules remplacée par ['event:auth-loginRequired', 'event:auth-loginConfirmed']
ne fonctionne pas non plus.
Qu'est-ce qui fonctionne, c'est ceci:
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');
});
}
};
});
Mais ce n'est pas idéal.
Est-il possible de lier plusieurs événements à la même fonction en une seule fois?
Oui. Comme ça:
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');});
}
};
});
Mais ce n'est pas parce que vous le pouvez que vous devriez :). Si les événements continuent de se propager à un autre auditeur et qu'ils y sont traités différemment, il y a peut-être lieu de le faire. Si cela doit être le seul auditeur, vous devez simplement émettre (ou diffuser) le même événement.
Les autres réponses (Anders Ekdahl) sont correctes à 100% ... choisissez-en une ... MAIS ...
Sauf cela, vous pouvez toujours lancer le vôtre:
// 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');
});
}
};
});
Je suppose que si vous vouliez vraiment faire la .split(',')
vous le pouviez, mais c'est un détail d'implémentation.
AngularJS ne prend pas en charge la liaison d'événements multiples, mais vous pouvez faire quelque chose comme ceci:
var handler = function () { ... }
angular.forEach("event:auth-loginRequired event:auth-loginConfirmed".split(" "), function (event) {
scope.$on(event, handler);
});
Je ne pense pas que ce soit possible, car l'événement pourrait envoyer des données au rappel, et si vous écoutez plusieurs événements, vous ne sauriez pas quelles données provenaient de quel événement.
J'aurais fait quelque chose comme ça:
function listener() {
console.log('event fired');
}
scope.$on('event:auth-loginRequired', listener);
scope.$on('event:auth-loginConfirmed', listener);
Comme avec $ rootScope. $ OnMany (solution de @ ben-lesh) il est possible d'étendre la méthode $ 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);
});
};
a pris de ici .