请注意,我们在这里谈论的是两种略有不同的清理方式:
- 事件侦听器函数可能需要清理。
- 创建的元素也可能需要清理。
在这些情况下,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 只会破坏 inside 你的作用域或 包含在你的指令根元素的 DOM 中的所有东西。您聆听的所有其他内容,或您在指令之外创建和放置的元素,都是您的责任。
引用 Angular 文档,您可以通过监听销毁事件来进行清理:
最佳实践:指令应自行清理。你可以
使用 element.on('$destroy', ...) 或 scope.$on('$destroy', ...) 运行
删除指令时的清理功能。
我个人仅在需要清理的时候才添加这些方法。您需要这样做,特别是如果您为外部事件创建注册元素(即来自 websockets 的消息,或计划的超时事件),否则您可能会为同一事件结束多个侦听器(通常会导致行为不端和反应迟缓)。