Angular 如何在销毁组件时销毁事件处理程序和 属性 绑定
How does Angular destroy event handlers and property bindings when a component is destroyed
我试图了解 Angular 组件的销毁过程,比我在文档中找到的要详细一些。我希望这里有人能够回答以下问题:
是否在移除组件模板中的元素的事件侦听器之前移除这些元素的属性?
在Component的销毁过程中,事件监听器的注销是什么时候发生的,如何发生的?
在 Angular 中是否有关于在内部删除事件侦听器的过程的更多信息?
在 JavaScript 中,您无法删除 DOM 节点本身。如果您有以下 DOM 树:
div.children
span
到 "destroy" 一个跨度,您只需将它从 div.children
中删除。如果没有更多链接指向 span
元素,它将被垃圾回收。对象也是如此。
设想Angular中的以下结构:
ComponentA.nodes
ComponentBElement -> ComponentBClass
现在 Angular 需要 "destroy" ComponentB
。为此,它只需将 ComponentBElement
从父 ComponentA.nodes
中分离出来。这就是 Angular 所做的,例如,当您执行 viewContainerRef.clear()
:
function execRenderNodeAction(...) {
const renderer = view.renderer;
switch (action) {
...
case RenderNodeAction.RemoveChild:
renderer.removeChild(parentNode, renderNode);
break;
现在,假设 Angular 向 ComponentBElement
或其子项添加了一些事件侦听器。
是否需要显式调用removeEventListners
? Usually no, because once DOM elements are removed the event listeners are garbage collected as well. However, there's a possibility that a reference to the event listener is captured in some async task or an object that continues to live. This prevents the listener and the DOM from being garbage collected. So Angular ensures that event listeners are removed (in v5 it's DomEventsPlugin.removeEventListener 方法)。
当 Angular 创建组件视图时它调用 listenToElementOutputs:
function listenToElementOutputs(view, compView, def, el) {
for (var i = 0; i < def.outputs.length; i++) {
...
var disposable = listenerView.renderer.listen(listenTarget || el, output.eventName, handleEventClosure));
((view.disposables))[def.outputIndex + i] = disposable; <------
}
}
您可以看到事件是使用 renderer
附加的,然后取消订阅回调(一次性)存储在 view.disposables
中。当 Angular 销毁视图时,将执行这些一次性用品并删除事件侦听器。:
function [destroyView](view) {
...
if (view.disposables) {
for (var i = 0; i < view.disposables.length; i++) {
view.disposables[i](); <----------------
}
}
要了解有关视图和编译的更多信息,请阅读:
我试图了解 Angular 组件的销毁过程,比我在文档中找到的要详细一些。我希望这里有人能够回答以下问题:
是否在移除组件模板中的元素的事件侦听器之前移除这些元素的属性?
在Component的销毁过程中,事件监听器的注销是什么时候发生的,如何发生的?
在 Angular 中是否有关于在内部删除事件侦听器的过程的更多信息?
在 JavaScript 中,您无法删除 DOM 节点本身。如果您有以下 DOM 树:
div.children
span
到 "destroy" 一个跨度,您只需将它从 div.children
中删除。如果没有更多链接指向 span
元素,它将被垃圾回收。对象也是如此。
设想Angular中的以下结构:
ComponentA.nodes
ComponentBElement -> ComponentBClass
现在 Angular 需要 "destroy" ComponentB
。为此,它只需将 ComponentBElement
从父 ComponentA.nodes
中分离出来。这就是 Angular 所做的,例如,当您执行 viewContainerRef.clear()
:
function execRenderNodeAction(...) {
const renderer = view.renderer;
switch (action) {
...
case RenderNodeAction.RemoveChild:
renderer.removeChild(parentNode, renderNode);
break;
现在,假设 Angular 向 ComponentBElement
或其子项添加了一些事件侦听器。
是否需要显式调用removeEventListners
? Usually no, because once DOM elements are removed the event listeners are garbage collected as well. However, there's a possibility that a reference to the event listener is captured in some async task or an object that continues to live. This prevents the listener and the DOM from being garbage collected. So Angular ensures that event listeners are removed (in v5 it's DomEventsPlugin.removeEventListener 方法)。
当 Angular 创建组件视图时它调用 listenToElementOutputs:
function listenToElementOutputs(view, compView, def, el) {
for (var i = 0; i < def.outputs.length; i++) {
...
var disposable = listenerView.renderer.listen(listenTarget || el, output.eventName, handleEventClosure));
((view.disposables))[def.outputIndex + i] = disposable; <------
}
}
您可以看到事件是使用 renderer
附加的,然后取消订阅回调(一次性)存储在 view.disposables
中。当 Angular 销毁视图时,将执行这些一次性用品并删除事件侦听器。:
function [destroyView](view) {
...
if (view.disposables) {
for (var i = 0; i < view.disposables.length; i++) {
view.disposables[i](); <----------------
}
}
要了解有关视图和编译的更多信息,请阅读: