queryselector example angularjs memory-leaks

example - ng-bind-html angularjs



AngularJS-¿$ destroy elimina a los oyentes del evento? (1)

Oyentes de eventos

En primer lugar, es importante comprender que hay dos tipos de "escuchas de eventos":

  1. Los oyentes del evento Scope se registraron a través de $on :

    $scope.$on(''anEvent'', function (event, data) { ... });

  2. Controladores de eventos adjuntos a elementos a través de, por ejemplo, on o bind :

    element.on(''click'', function (event) { ... });

$ scope. $ destroy ()

Cuando se ejecuta $scope.$destroy() , se eliminarán todos los oyentes registrados a través de $on en ese $ scope.

No eliminará los elementos DOM ni los controladores de eventos adjuntos del segundo tipo.

Esto significa que llamar a $scope.$destroy() manualmente desde un ejemplo dentro de la función de enlace de una directiva no eliminará un controlador adjunto a través de, por ejemplo, element.on , ni el elemento DOM en sí.

element.remove ()

Tenga en cuenta que remove es un método jqLite (o un método jQuery si jQuery se carga antes de AngularjS) y no está disponible en un objeto de elemento DOM estándar.

Cuando se element.remove() ese elemento y todos sus elementos element.remove() se eliminarán del DOM juntos, todos los controladores de eventos se adjuntarán mediante, por ejemplo, element.on .

No destruirá el $ alcance asociado con el elemento.

Para hacerlo más confuso, también hay un evento jQuery llamado $destroy . A veces, cuando se trabaja con bibliotecas jQuery de terceros que eliminan elementos, o si los elimina manualmente, es posible que deba realizar una limpieza cuando eso ocurra:

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

Qué hacer cuando una directiva es "destruida".

Esto depende de cómo se "destruye" la directiva.

Un caso normal es que una directiva se destruye porque ng-view cambia la vista actual. Cuando esto suceda, la directiva ng-view destruirá el ámbito $ asociado, dividirá todas las referencias a su ámbito principal y llamará remove() en el elemento.

Esto significa que si esa vista contiene una directiva con esto en su función de enlace cuando es destruido por ng-view :

scope.$on(''anEvent'', function () { ... }); element.on(''click'', function () { ... });

Ambos oyentes de eventos serán eliminados automáticamente.

Sin embargo, es importante tener en cuenta que el código dentro de estos escuchas aún puede causar pérdidas de memoria, por ejemplo, si ha alcanzado las circular references comunes del patrón de pérdida de memoria JS.

Incluso en este caso normal de una directiva que se destruye debido a un cambio de vista, hay cosas que puede necesitar limpiar manualmente.

Por ejemplo, si ha registrado un oyente en $rootScope :

var unregisterFn = $rootScope.$on(''anEvent'', function () {}); scope.$on(''$destroy'', unregisterFn);

Esto es necesario ya que $rootScope nunca se destruye durante la vida útil de la aplicación.

Lo mismo ocurre si está utilizando otra implementación de pub / sub que no realiza automáticamente la limpieza necesaria cuando se destruye $ scope, o si su directiva pasa las devoluciones de llamada a los servicios.

Otra situación sería cancelar $interval / $timeout :

var promise = $interval(function () {}, 1000); scope.$on(''$destroy'', function () { $interval.cancel(promise); });

Si su directiva adjunta controladores de eventos a elementos, por ejemplo, fuera de la vista actual, también debe limpiarlos manualmente:

var windowClick = function () { ... }; angular.element(window).on(''click'', windowClick); scope.$on(''$destroy'', function () { angular.element(window).off(''click'', windowClick); });

Estos fueron algunos ejemplos de qué hacer cuando las directivas son "destruidas" por Angular, por ejemplo, por ng-view o ng-if .

Si tiene directivas personalizadas que administran el ciclo de vida de los elementos DOM, etc., por supuesto, se volverá más complejo.

https://docs.angularjs.org/guide/directive

Al escuchar este evento, puede eliminar los escuchas de eventos que pueden causar pérdidas de memoria. Los oyentes registrados en ámbitos y elementos se limpian automáticamente cuando se destruyen, pero si registra un oyente en un servicio, o si registra un oyente en un nodo DOM que no se está eliminando, deberá limpiarlo usted mismo corre el riesgo de introducir una pérdida de memoria.

Mejores prácticas: las directivas deben limpiarse después de ellas mismas. Puede usar element.on (''$ destroy'', ...) o scope. $ On (''$ destroy'', ...) para ejecutar una función de limpieza cuando se elimina la directiva.

Pregunta:

Tengo un element.on "click", (event) -> dentro de mi directiva:

  1. Cuando se destruye la directiva, ¿hay alguna referencia de memoria a element.on para evitar que se recoja la basura?
  2. La documentación angular indica que debo usar un controlador para eliminar escuchas de eventos en el evento $destroy emitted. Tenía la impresión de que destroy() eliminó a los oyentes del evento, ¿no es así?