Em alguns aplicativos da web, é possível ter objetos singleton que são instanciados uma vez, mas inicializados com frequência. Por exemplo (suponha jQuery):
(function(window){
window.MyNamespace = window.MyNamespace || {};
var MySingleton = MyNamespace.MySingleton = {
init: function() {
//init code
}
}
MySingleton.init(); //init on load
})(window);
O código acima adiciona um singleton ao seu namespace global (que pode ser referenciado por MyNamespace.MySingleton
outro lugar em seu código). Muitas vezes, na init()
função, ocorre a associação de eventos:
init: function() {
this.elem = $('#myelem');
//wire events to this specific element
this.elem
.on('click', '.myclass1', this.handleClick)
.on('change', '.myclass2', this.handleChange)
//etc
;
//wire events to doc, like triggered custom events
$(document)
.on('customevent', this.handleCustomEvent)
//etc
;
}
Isso é bom se o elemento principal de seus objetos permanecer no DOM e seu singleton não for init
refeito. Mas e se você tiver um webapp que carregue dinamicamente o seu HTML, substituindo o que estava lá antes? Seus elementos DOM serão religados com sucesso (supondo que você tenha novos elementos DOM), mas seus document
eventos serão religados, o que significa que eles reagirão um número crescente de vezes conforme os usuários folhearem seu aplicativo.
Lidar com isso é simples: crie uma hasBound
propriedade em seu singleton (exemplo simplificado):
var MySingleton = {
hasBound: false
, init: function() {
// [ DOM wireup ]
if (!this.hasBound) {
// [ document wireup ]
this.hasBound = true;
}
}
}
Agora você pode reconfigurar init
seu singleton com segurança, sem se preocupar com a multi-ligação de seus eventos!