AngularJS - $destroy 是否删除事件监听器?
https://docs.angularjs.org/guide/directive
通过侦听此事件,您可以删除可能导致内存泄漏的事件侦听器。注册到作用域和元素的侦听器在销毁时会自动清理,但是如果您在服务上注册了侦听器,或者在未被删除的
DOM 节点上注册了侦听器,则必须自己清理或您可能会引入内存泄漏。最佳实践:指令应自行清理。您可以使用 element.on(‘$destroy’, …) 或 scope.$on(‘$destroy’, …)
在删除指令时运行清理功能。
问题:
element.on "click", (event) ->
我的指令里面有一个:
- 当指令被销毁时,是否有任何内存引用来
element.on
防止它被垃圾收集? - Angular 文档指出我应该使用处理程序来删除
$destroy
发出事件的事件侦听器。我的印象是destroy()
删除了事件侦听器,不是这样吗?
-
事件监听器
首先,重要的是要了解有两种“事件侦听器”:
-
通过以下方式注册的范围事件侦听器
$on
:$scope.$on('anEvent', function (event, data) {
…
}); -
通过例如
on
或附加到元素的事件处理程序bind
:element.on('click', function (event) {
…
});
$scope.$destroy()
执行时
$scope.$destroy()
,它将删除通过$on
该 $scope 注册的所有侦听器。它 不会 删除 DOM 元素或任何附加的第二类事件处理程序。
这意味着
$scope.$destroy()
在指令的链接函数中从 example 手动调用不会删除通过 example
附加的处理程序element.on
,也不会删除 DOM 元素本身。
element.remove()
请注意,这
remove
是一个 jqLit​​e 方法(如果 jQuery 在 AngularjS 之前加载,则为 jQuery 方法)并且在标准
DOM 元素对象上不可用。当
element.remove()
执行时,该元素及其所有子元素将一起从 DOM 中删除,所有事件处理程序将通过例如element.on
.它 不会 破坏与元素关联的 $scope。
为了使它更加混乱,还有一个名为
$destroy
. 有时在使用删除元素的第三方 jQuery
库时,或者如果您手动删除它们,您可能需要在发生这种情况时执行清理:element.on('$destroy', function () { scope.$destroy(); });
当指令被“销毁”时该怎么办
这取决于指令是如何“销毁”的。
一个正常的情况是指令被破坏,因为
ng-view
改变了当前视图。发生这种情况时,该ng-view
指令将销毁关联的
$scope,切断对其父范围的所有引用并调用remove()
该元素。这意味着如果该视图在其链接函数中包含一个带有 this 的指令,则当它被销毁时
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
在应用程序的生命周期内永远不会被破坏。如果您使用的另一个发布/订阅实现在 $scope 被销毁时不会自动执行必要的清理,或者您的指令将回调传递给服务,则同样如此。
另一种情况是取消
$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); });
这些是当指令被 Angular “销毁”时该怎么做的一些例子,例如通过
ng-view
orng-if
。如果您有管理 DOM 元素等生命周期的自定义指令,它当然会变得更加复杂。
-
-
AngularJS-$ destroy是否会删除事件监听器?
2021-02-01 关注 0 浏览85 1答案
-
删除匿名事件监听器
2021-02-02 关注 0 浏览65 1答案
-
在卸载React上删除事件监听器
2021-01-31 关注 0 浏览151 1答案
-
如何检查动态附加的事件监听器是否存在?
2022-07-28 关注 0 浏览11 1答案
-
Zookeeper Watcher(事件监听器)?
2020-11-26 关注 0 浏览714 1答案
-
SQLAlchemy Mixins /和事件监听器
2021-01-29 关注 0 浏览100 1答案
-
什么是被动事件监听器?
2021-02-02 关注 0 浏览181 1答案
-
什么是被动事件监听器?
2022-05-26 关注 0 浏览17 1答案
-
Android自定义事件监听器
2021-01-29 关注 0 浏览805 1答案
-
JavaScript自定义事件监听器
2021-02-02 关注 0 浏览97 1答案