2013-07-25 10 views
21

C'è una perdita di memoria pesante nella mia applicazione, ma non ho trovato le cause, e qui è lo sfondo.Abbiamo bisogno di sciogliere gli ascoltatori di eventi nelle direttive quando l'angolare inizia a distruggere?

  • Sto usando AngularJS + JQuery (plugin)
  • Molti ascoltatori sono legati come la seguente:

    $ (elemento) .on ("KeyUp", function() {});

Quindi la domanda è

Devo sciogliere quegli ascoltatori nelle direttive seguendo?

scope.$on("$destroy", function() { 
    $(element).off(); 
}); 

BTW, come si rileva solitamente la perdita di memoria in un'applicazione Web? Io uso il profilo di Chrome (vedi qui Profiling memory performance) ma non ho potuto rintracciare i codici in cui la memoria perde. Hai qualche suggerimento?

Grazie mille!

+0

Non credo che questo è necessaria a meno che si sono vincolanti tutti gli ambiti a $ rootScope. –

+1

Non è necessario rimuoverli, di solito vengono raccolti. È possibile che si desideri rimuovere gli ascoltatori della finestra, ad esempio lo scorrimento o gli eventi dei messaggi se il gestore interagisce con gli elementi dell'ambito. Vedi http://stackoverflow.com/questions/12528049/if-a-dom-element-is-removed-are-its-listeners-also-removed-from-memory – Kapep

risposta

14

La documentazione angolare per l'ambito destroy, implica che è necessario rimuovere gli eventi DOM.

http://docs.angularjs.org/api/ng.$rootScope.Scope#$destroy

Si noti che, in AngularJS, v'è anche un evento di distruggere jQuery $, che può essere utilizzato per pulire le associazioni DOM prima di un elemento viene rimosso dalla DOM.

+0

grazie per la tua risposta, ho smesso di ascoltare quegli ascoltatori $ distrugge il processo, ma non sembra utile al mio problema di perdita di memoria. hmm ... – Edward

+0

Ho appena scoperto che l'evnet $ destroy viene effettivamente attivato dopo che la dom è stata rimossa nel mio caso :(tempo di inviare un altro bug penso – Blowsie

+1

@Blowsie Ci sono 2 tipi di $ destroy event. one is $ scope $ on ('$ destroy', cb) che viene chiamato prima della rimozione degli elementi.Un altro è element.on ('$ destroy', cb) che è un evento jQ e viene chiamato dopo la rimozione degli elementi. –

4

Non posso essere d'accordo con la risposta accettata, la perdita di memoria potrebbe avere altre cause.

Partenza questo per una risposta eccellente: AngularJS - Does $destroy remove event listeners?

+0

Ho controllato quel post ma non capisco perché la pensi così? la risposta sopra che abbiamo bisogno di rimuovere manualmente quei listener creati da JQuery quando l'ambito è distrutto.BBW, il mio problema di memoria è stato risolto dopo aver rimosso gli ascoltatori – Edward

+3

Quando Angular rimuove un elemento associato a una direttiva, chiama jQuery/jqLite '$ elem.remove()' funzione, che si suppone che rimuova qualsiasi listener di eventi di questo elemento e elementi figlio."ripulire i collegamenti DOM" può riferirsi ad eventi legati a 'window' o' document', o elementi tenuti in memoria e aggiunti/rimossi programmaticamente dal dom (magari usando 'append' e' detach') –

+5

entrambe le risposte sono parzialmente corretto: le chiamate angolari vengono rimosse, ma ciò annullerebbe la registrazione degli eventi registrati con l'elemento su cui si trova la direttiva e i relativi discendenti. Se dovessi registrare un gestore di eventi su un nodo esterno (ad esempio il documento per esempio), non verrebbe pulito. Lo stesso vale per gli elementi DOM che sono staccato dall'albero DOM durante $ destroy – BiAiB