请注意,这里涉及到两种略微不同的清理方式:
- 事件监听函数可能需要清理。
- 创建的元素也可能需要清理。
在这些情况下,Angular 会为您进行清理:
$scope.$watch("scopeVariable", function (newVal) { ... });
$scope.$watch("injectedService.serviceVar", function (newVal) { ... } );
$scope.$on("event", function () { ... });
element.on('click', function() { ... });
在这些情况下,不需要进行任何清理。Angular知道某些代码正在监听事件或监视变量,并能够注销它们。对于该元素,由于它将被移除,所有闭包和相关对象都将被取消引用,因此稍后会被垃圾回收器处理。
另一方面,在以下情况下,Angular不会为您执行清理操作:
$rootScope.$on("event", function () { ... });
someInjectedService.subscribeIncomingMessage(function () { ... });
var body = $document.find('body').eq(0);
var newElement = angular.element('<div></div>');
body.append(newElement);
body.on("click", function() { ... });
在这些情况下,Angular 永远不会销毁您的监听器,也不会销毁添加到文档
<body>
的创建元素。
换句话说,Angular 只会销毁您指令根元素作用域内的所有内容或包含在 DOM 中的所有内容。您监听的其他所有内容或在指令外部创建和放置的元素都是您的责任。
引用 Angular 文档的话,您可以通过监听销毁事件来进行清理:
最佳实践:指令应该自我清理。您可以使用
element.on('$destroy', ...)
或
scope.$on('$destroy', ...)
运行清理函数,以便在指令被移除时进行清理。
我个人只在需要清理时才添加这些方法。特别是如果您创建元素或注册外部事件(例如来自 WebSockets 的消息或计划的超时事件),则必须这样做,否则您可能会出现多个监听器监听同一事件(通常会导致错误和缓慢)。