La réponse de @LiviuT est géniale, mais semble laisser beaucoup de gens se demander comment accéder à nouveau à la fonction de destruction du gestionnaire à partir d'un autre $scope ou d'une autre fonction, si vous voulez le détruire à partir d'un endroit autre que celui où il a été créé. La réponse de @ fonctionne très bien, mais n'est pas très idiomatique. (Et s'appuie sur ce qui est censé être un détail d'implémentation privé, qui pourrait changer à tout moment). Et à partir de là, ça devient de plus en plus compliqué...
Je pense que la réponse facile ici est de simplement porter une référence à la fonction de démolition ( offCallMeFn
dans son exemple) dans le gestionnaire lui-même, puis l'appeler en fonction d'une condition ; peut-être une arg que vous incluez dans l'événement que vous $broadcast ou $emit. Les gestionnaires peuvent ainsi se détruire eux-mêmes, quand vous le voulez, où vous le voulez, en transportant les graines de leur propre destruction. Par exemple :
// Creation of our handler:
var tearDownFunc = $rootScope.$on('demo-event', function(event, booleanParam) {
var selfDestruct = tearDownFunc;
if (booleanParam === false) {
console.log('This is the routine handler here. I can do your normal handling-type stuff.')
}
if (booleanParam === true) {
console.log("5... 4... 3... 2... 1...")
selfDestruct();
}
});
// These two functions are purely for demonstration
window.trigger = function(booleanArg) {
$scope.$emit('demo-event', booleanArg);
}
window.check = function() {
// shows us where Angular is stashing our handlers, while they exist
console.log($rootScope.$$listeners['demo-event'])
};
// Interactive Demo:
>> trigger(false);
// "This is the routine handler here. I can do your normal handling-type stuff."
>> check();
// [function] (So, there's a handler registered at this point.)
>> trigger(true);
// "5... 4... 3... 2... 1..."
>> check();
// [null] (No more handler.)
>> trigger(false);
// undefined (He's dead, Jim.)
Deux pensées :
- C'est une excellente formule pour un handler de type run-once. Il suffit de laisser tomber les conditionnels et de lancer
selfDestruct
dès qu'il aura terminé sa mission suicide.
- Je me demande si la portée d'origine sera jamais correctement détruite et collectée, étant donné que vous transportez des références à des variables fermées. Il faudrait en utiliser un million pour que ce soit un problème de mémoire, mais je suis curieux. Si quelqu'un a une idée, merci de la partager.
3 votes
Pour ceux qui se posent la question, la fonction retournée est documentée ici