当前位置: 首页 > 面试题库 >

AngularJS-$ destroy是否会删除事件监听器?

訾安邦
2023-03-14
问题内容

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

通过侦听此事件,可以删除可能导致内存泄漏的事件侦听器。注册到范围和元素的侦听器在销毁时会自动清除,但是如果您在服务上注册了侦听器,或者在未删除的DOM节点上注册了侦听器,则必须自己清理或您可能会引入内存泄漏的风险。

最佳实践:指令应自行清理。删除指令后,可以使用element.on(’$ destroy’,…)或scope。$ on(’$
destroy’,…)运行清理函数。

题:

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

  1. 伪指令销毁后,是否有对的内存引用,element.on以防止其被垃圾回收?
  2. Angular文档指出,我应该使用处理程序删除$destroy发出的事件上的事件侦听器。我的印象是destroy()删除了事件监听器,不是吗?

问题答案:

事件监听器

首先,重要的是要了解有两种“事件侦听器”:

  1. 范围事件侦听器通过$on以下方式注册:

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


    });

  2. 通过例如on或附加到元素的事件处理程序bind

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


    });

$ scope。$ destroy()

$scope.$destroy()执行时,它将删除通过$on该$ scope 注册的所有侦听器。

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

这意味着$scope.$destroy()从指令的链接函数内的示例中手动调用将不会删除通过example附加的处理程序element.on,也不会删除DOM元素本身。

element.remove()

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

element.remove()执行该元素及其所有子元素时,将从所有DOM中一起删除所有事件处理程序,例如element.on

不会 破坏与该元素关联的$ scope。

为了使其更加混乱,还有一个名为的jQuery事件$destroy。有时,当使用删除元素的第三方jQuery库时,或者如果手动删除它们,则可能需要在发生这种情况时执行清理:

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

指令被“销毁”时该怎么办

这取决于该指令如何被“销毁”。

通常情况是由于ng-view更改当前视图而导致指令被销毁。发生这种情况时,ng-view指令将销毁关联的$
scope,切断对其父作用域的所有引用,并调用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实现,当$ 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或)“销毁”指令时的操作示例ng-if

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



 类似资料:
  • 问题内容: 无论如何,要删除这样添加的事件侦听器: 不更换元素? 问题答案: 除非您在创建时存储了对事件处理程序的引用,否则无法彻底删除事件处理程序。 我通常会将它们添加到该页面上的主要对象中,然后在处理完该对象后可以对其进行迭代和清理。

  • 问题内容: 我在反应中有更高阶的组件是这样的: 卸载通过包装的组件后,它们仍然会抛出错误,例如(当我滚动时): 警告:setState(…):只能更新已安装或正在安装的组件。这通常意味着您在未安装的组件上调用了setState()。这是无人值守。请检查未定义组件的代码。 即使确实删除了组件卸载中的事件。没用 但是当我将代码更改为这样时: 一切似乎都正常,没有任何问题。 我觉得它们是完全一样的,但是

  • 问题内容: 我是NodeJS的新手,正在学习它如何与流一起工作。读一本书,我发现了以下示例代码: 在此代码段中,我们先调用method,然后等待回调( 第1部分 )。 在下一行,我们正在监听事件( 第2部分 )。 问题: 如果在第1部分和第2部分之间发生延迟,那么首先执行第1部分的回调(在第2部分开始侦听事件之前。那是真的会丢失第一个数据块)吗? 问题答案: 不,因为您 不是在“等待” 回调。回调

  • 本文向大家介绍什么是事件监听?相关面试题,主要包含被问及什么是事件监听?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: addEventListener()方法,用于向指定元素添加事件句柄,它可以更简单的控制事件,语法为 element.addEventListener(event, function, useCapture); 第一个参数是事件的类型(如 "click" 或 "mouse

  • Blade 中提供一个方法帮助开发者可以自定义的监听应用程序运行中的一些生命周期。比如 Session 的创建与销毁,应用启动结束后等。 支持的事件类型有如下: public enum EventType { SERVER_STARTING, // 服务准备启动 SERVER_STARTED, // 服务启动成功 SERVER_STOPPING, //

  • Nutz.Ioc 容器有三种事件: 对象被创建(create事件) 对象被从容器中取出(fetch事件) 对象被销毁(depose事件) 在这三种时刻,你如果想做一些特殊的操作,比如,当一个数据源被销毁时,你希望能够关闭所有的连接, 声明一下,你想监听什么事件,以及怎么监听。 注: 如果你的对象是 "singleton: false",那么容器创建了对象后就会立即忘记它的存在。因为鬼才知道 你打算