La risposta di @ LiviuT è fantastica, ma sembra lasciare molte persone a chiedersi come riaccedere alla funzione di smontaggio del gestore da un altro $ scope o funzione, se si desidera distruggerla da un luogo diverso da dove è stata creata. La risposta di @ Рустем Мусабеков funziona benissimo, ma non è molto idiomatica. (E si basa su quello che dovrebbe essere un dettaglio di implementazione privato, che potrebbe cambiare in qualsiasi momento.) E da lì, diventa solo più complicato ...
Penso che la risposta facile qui sia semplicemente portare un riferimento alla funzione di abbattimento ( offCallMeFn
nel suo esempio) nel gestore stesso, e poi chiamarlo in base a qualche condizione; forse un argomento che includi nell'evento che $ trasmetti o $ emetti. I gestori possono così abbattere se stessi, quando vuoi, dove vuoi, portando in giro i semi della loro stessa distruzione. Così:
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();
}
});
window.trigger = function(booleanArg) {
$scope.$emit('demo-event', booleanArg);
}
window.check = function() {
console.log($rootScope.$$listeners['demo-event'])
};
>> trigger(false);
>> check();
>> trigger(true);
>> check();
>> trigger(false);
Due pensieri:
- Questa è un'ottima formula per un gestore run-once. Lascia cadere i condizionali e corri
selfDestruct
non appena ha completato la sua missione suicida.
- Mi chiedo se l'ambito di origine verrà mai correttamente distrutto e raccolto in modo spazzatura, dato che stai portando riferimenti a variabili chiuse. Dovresti usarne un milione anche solo per avere un problema di memoria, ma sono curioso. Se qualcuno ha qualche intuizione, per favore condividi.