https://docs.angularjs.org/guide/directive
通过监听此事件,你可以移除事件侦听器可能会导致内存泄漏。 登记范围和内容监听器将自动清除这些被破坏的时候,但如果你注册了一个服务侦听器,或者注册一个没有被删除的DOM节点上的监听器,你就必须清理自己或你可能会引入内存泄漏。
最佳实践:指令后应自行清理。 您可以使用element.on(“$摧毁”,......)或范围。在$(“$摧毁”,...)当该指令被删除运行清理功能。
题:
我有一个element.on "click", (event) ->
我的指令内:
- 当该指令被破坏,有没有到任何内存引用
element.on
以防止它被垃圾回收? - 我应该使用一个处理程序,在移除事件侦听角文档状态
$destroy
发射事件。 我是印象中destroy()
删除事件监听器,这是不是这样的?
事件侦听器
首先是要明白,有两种“事件侦听器”的非常重要的:
经登记的经营范围事件侦听器$on
:
$scope.$on('anEvent', function (event, data) { ... });
附接至通过例如元素事件处理程序on
或bind
:
element.on('click', function (event) { ... });
$范围。$摧毁()
当$scope.$destroy()
执行它会删除通过注册的所有监听器$on
上$范围。
它不会删除DOM元素或第二类的任何附加事件处理程序。
这意味着,调用$scope.$destroy()
从例如手动一个指令的链接功能内不会删除通过例如连接处理程序element.on
,也不是DOM元素本身。
element.remove()
注意, remove
是jqLite方法(或者如果jQuery是AngularjS之前加载一个jQuery方法),并且是不可用在标准DOM元素对象。
当element.remove()
被执行的元件和其所有子将从DOM中移除一起将通过例如附连所有事件处理程序element.on
。
它不会破坏与相关联的元素$范围。
为了让更多的混乱也有称为一个jQuery事件$destroy
。 有时与删除元素,或者如果你手动删除它们,则可能需要进行清理发生在第三方的jQuery库工作时:
element.on('$destroy', function () {
scope.$destroy();
});
怎么办时,一个指令“破坏”
这取决于如何指令“破坏”。
正常的情况是,一个指令被销毁,因为ng-view
改变当前视图。 当这种情况发生了ng-view
指令将销毁关联$范围内,断绝一切引用它的父范围和调用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实现,当$范围破坏不会自动执行必要的清理,或者如果你的指令传递回调服务。
另一种情况是,取消$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);
});
这些人的指令时,被“破坏”的角,例如什么做一些例子ng-view
或ng-if
。
如果您有管理的DOM元素的生命周期等自定义指令它当然会变得更加复杂。