By listening to this event,you can remove event listeners that might cause memory leaks. Listeners registered to scopes and elements are automatically cleaned up when they are destroyed,but if you registered a listener on a service,or registered a listener on a DOM node that isn’t being deleted,you’ll have to clean it up yourself or you risk introducing a memory leak.
Best Practice: Directives should clean up after themselves. You can use element.on(‘$destroy’,…) or scope.$on(‘$destroy’,…) to run a clean-up function when the directive is removed.
题:
我有一个element.on“click”,(event) – >在我的指令:
>当指令被销毁时,是否有任何内存引用element.on以防止它被垃圾回收?
> Angular文档声明,我应该使用一个处理程序来删除$ destroy emit事件上的事件监听器。我的印象是,destroy()删除事件侦听器,这是不是这样?
首先,了解有两种“事件侦听器”很重要:
>范围通过$ on注册的事件侦听器:
$scope.$on('anEvent',function (event,data) { ... });
>通过例如on或bind将事件处理程序附加到元素:
element.on('click',function (event) { ... });
$ scope。$ destroy()
当$ scope。$ destroy()被执行时,它将删除在$ scope上通过$ on注册的所有监听器。
它不会删除DOM元素或任何附加的第二种事件处理程序。
这意味着在指令的链接函数中从示例手动调用$ scope。$ destroy()不会删除通过例如element.on附加的处理程序,也不会删除DOM元素本身。
element.remove()
注意,remove是一个jqLite方法(如果jQuery在AngularjS之前加载,则为jQuery方法),并且在标准DOM元素对象上不可用。
当element.remove()被执行时,该元素及其所有子元素将一起从DOM中移除,所有事件处理程序通过例如element.on附加。
它不会销毁与元素相关联的$ scope。
为了使它更混乱,还有一个称为$ destroy的jQuery事件。有时,当使用第三方jQuery库删除元素,或者如果您手动删除它们,您可能需要执行清理时发生:
element.on('$destroy',function () { scope.$destroy(); });
当指令被“销毁”时该怎么办
这取决于指令是如何“销毁”的。
正常情况是指令被销毁,因为ng-view改变了当前视图。当这种情况发生时,ng-view指令将会销毁相关联的$ scope,将所有对其父scope的引用都关闭,并在元素上调用remove()。
这意味着如果该视图在其链接函数中包含一个指令,当它被ng-view销毁时:
scope.$on('anEvent',function () { ... }); element.on('click',function () { ... });
然而,重要的是要注意,这些监听器中的代码仍然可能导致内存泄漏,例如,如果你已经实现了常见的JS内存泄漏模式循环引用。
即使在这个正常的情况下,一个指令被毁坏,由于视图更改,有一些事情,你可能需要手动清理。
例如,如果您在$ 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元素的生命周期等,它当然会变得更复杂。