https://docs.angularjs.org/guide/directive
注册范围和元素的监听器是 当它们被摧毁时自动清理,但如果你 在服务上注册了一个监听器,或者在DOM上注册了一个监听器 没有删除的节点,你必须自己清理它 你冒着引入内存泄漏的风险。
我不明白一件事(实际上我并不了解很多关于Angular的事情,但现在我的目标正是针对这一点)。任何人都可以解释注册的到范围和元素“和”之间的区别“>>在服务上注册了一个监听器,或者注册了一个监听器< strong> on 一个DOM“。这句话中元素和DOM之间的区别是什么。为什么在第一种情况下,监听器会被自动清理,但在第二种情况下它们不会被清除。为什么要注册到元素以及在 DOM上注册的内容?
答案 0 :(得分:4)
请注意,我们在这里谈到两种略有不同的清理方式:
在这些情况下,Angular会为您清理:
// Watching scope vars
$scope.$watch("scopeVariable", function (newVal) { ... });
$scope.$watch("injectedService.serviceVar", function (newVal) { ... } );
// Listening to events from a scope
$scope.$on("event", function () { ... });
// Events of the element of a directive,
// within the directive 'link' function (the docs you referenced)
element.on('click', function() { ... });
在所有这些情况下,没有必要进行任何清理。 Angular知道某些代码正在侦听事件或观察变量,并且可以取消注册它们。对于元素,因为它将被删除,所有闭包和相关对象将被取消引用,因此后来由垃圾收集器处理。
另一方面,在以下情况下,Angular不会为您进行清理:
// Listening to events from rootScope
$rootScope.$on("event", function () { ... });
// Subscribing to services events
someInjectedService.subscribeIncomingMessage(function () { ... });
// Adding elements outside directive container element
var body = $document.find('body').eq(0);
var newElement = angular.element('<div></div>');
body.append(newElement);
// Listening to events of elements outside your directive (ie. body)
body.on("click", function() { ... });
在这些情况下,Angular永远不会破坏您的侦听器,也不会将创建的元素添加到文档的<body>
中。
简单来说,我说Angular会破坏你的范围内 范围内的所有内容,或者你的指令根元素的DOM 中包含的。
,您有责任听取其他所有内容,或者您创建的内容以及放置在指令之外的内容。引用角度文档,您可以通过侦听destroy事件进行清理:
最佳实践:指令应该自行清理。您可以 使用
element.on('$destroy', ...)
或scope.$on('$destroy', ...)
来运行 删除指令时的清理功能。
我个人只有在需要清理时才添加这些方法。您需要这样做,特别是如果您为外部事件创建注册元素(即来自websockets或预定超时事件的消息),否则您可能会因为同一事件的多个侦听器而结束(通常会导致错误行为和迟缓)。 / p>