AngularJS - 是否$摧毁移除事件侦听器?AngularJS - 是否$摧毁移除事件侦听

2019-05-10 10:25发布

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

通过监听此事件,你可以移除事件侦听器可能会导致内存泄漏。 登记范围和内容监听器将自动清除这些被破坏的时候,但如果你注册了一个服务侦听器,或者注册一个没有被删除的DOM节点上的监听器,你就必须清理自己或你可能会引入内存泄漏。

最佳实践:指令后应自行清理。 您可以使用element.on(“$摧毁”,......)或范围。在$(“$摧毁”,...)当该指令被删除运行清理功能。

题:

我有一个element.on "click", (event) ->我的指令内:

  1. 当该指令被破坏,有没有到任何内存引用element.on以防止它被垃圾回收?
  2. 我应该使用一个处理程序,在移除事件侦听角文档状态$destroy发射事件。 我是印象中destroy()删除事件监听器,这是不是这样的?

Answer 1:

事件侦听器

首先是要明白,有两种“事件侦听器”的非常重要的:

  1. 经登记的经营范围事件侦听器$on

     $scope.$on('anEvent', function (event, data) { ... }); 
  2. 附接至通过例如元素事件处理程序onbind

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

$范围。$摧毁()

$scope.$destroy()执行它会删除通过注册的所有监听器$on上$范围。

不会删除DOM元素或第二类的任何附加事件处理程序。

这意味着,调用$scope.$destroy()从例如手动一个指令的链接功能内不会删除通过例如连接处理程序element.on ,也不是DOM元素本身。


element.remove()

注意, remove是jqLit​​e方法(或者如果jQuery是AngularjS之前加载一个jQuery方法),并且是不可用在标准DOM元素对象。

element.remove()被执行的元件和其所有子将从DOM中移除一起将通过例如附连所有事件处理程序element.on

不会破坏与相关联的元素$范围。

为了让更多的混乱也有称为一个jQuery事件$destroy 。 有时与删除元素,或者如果你手动删除它们,则可能需要进行清理发生在第三方的jQuery库工作时:

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

怎么办时,一个指令“破坏”

这取决于如何指令“破坏”。

正常的情况是,一个指令被销毁,因为ng-view改变当前视图。 当这种情况发生了ng-view指令将销毁关联$范围内,断绝一切引用它的父范围和调用remove()的元素。

这意味着,如果该视图包含与此在它的链接功能的指令,当它被摧毁ng-view

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

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

这两个事件侦听器将被自动删除。

然而,需要注意的是,这些听众中的代码仍然可以导致内存泄漏,例如,如果你已经实现了共同JS的内存泄漏模式是非常重要的circular references

即使在一个指令的这种通常情况下,由于被破坏掉了不断变化的景色有可能需要手动清理的东西。

例如,如果您已注册的侦听器$rootScope

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

scope.$on('$destroy', unregisterFn);

这是必要的,因为$rootScope从不应用程序的生命周期中被摧毁。

这同样,如果你使用的是其他的pub / sub实现,当$范围破坏不会自动执行必要的清理,或者如果你的指令传递回调服务。

另一种情况是,取消$interval / $timeout

var promise = $interval(function () {}, 1000);

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

如果你的指令将事件处理器当前视图之外的例如元素,你需要手动清理这些行动,以及:

var windowClick = function () {
   ...
};

angular.element(window).on('click', windowClick);

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

这些人的指令时,被“破坏”的角,例如什么做一些例子ng-viewng-if

如果您有管理的DOM元素的生命周期等自定义指令它当然会变得更加复杂。



文章来源: AngularJS - Does $destroy remove event listeners?