2017-10-11 45 views
1

我想了解Angular组件的销毁过程比我在文档中找到的更详细一点。我希望这里有人能够回答以下问题:当组件被销毁时,Angular销毁事件处理程序和属性如何绑定

组件模板中元素的属性在这些元素的事件侦听器被删除之前被删除?

在组件的销毁过程中,何时以及如何发生事件监听器的注销?

有没有关于在Angular中内部删除事件监听器的过程的更多信息?

回答

2

在JavaScript中,您无法删除一个DOM节点。如果你有以下DOM树:

div.children 
    span 

“摧毁”你只需从div.children删除它的跨度。如果没有更多指向span元素的链接,它将被垃圾收集。对于对象也是如此。

想象一下下面的结构角度:

ComponentA.nodes 
    ComponentBElement -> ComponentBClass 

角现在需要 “消灭” ComponentB。要做到这一点,它简单地从父母ComponentA.nodes分离ComponentBElement。这就是角呢,例如,当你执行viewContainerRef.clear()

function execRenderNodeAction(...) { 
    const renderer = view.renderer; 
    switch (action) { 
    ... 
    case RenderNodeAction.RemoveChild: 
     renderer.removeChild(parentNode, renderNode); 
     break; 

现在,假设角增加了一些事件监听器ComponentBElement或其子女。

是否有任何需要明确致电removeEventListnersUsually no,因为一旦DOM元素被移除,事件监听器也被垃圾收集。但是,可能会在某些异步任务或持续生存的对象中捕获对事件侦听器的引用。这可以防止垃圾收集器监听器和DOM。所以Angular确保事件监听器被移除(在v5中它的方法是DomEventsPlugin.removeEventListener)。

当角创建组件视图它调用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。当角销毁鉴于这些一次性执行和事件监听器被删除:

function [destroyView](view) { 
    ... 
    if (view.disposables) { 
     for (var i = 0; i < view.disposables.length; i++) { 
      view.disposables[i](); <---------------- 
     } 
    } 

要了解更多有关意见和编译阅读:

+0

谢谢为了澄清这一点对我来说!你是否也碰巧知道,在这个过程中的某个时刻,绑定到视图的属性是否被删除? Angular跟视图中的事件监听器一样跟踪这些吗? – MrMalt

+0

不客气,_属性必须视图_ - 你是什么意思?你能举个例子吗? –

+0

对不起,这有点不清楚。例如。 '

'。这里_border_,_height_和_width_类变量被绑定到_table_元素的相应属性(和属性)。我想知道的是,如果Angular在组件被销毁时对这些绑定做了任何事情,以及我可以在哪里找到更多有关Angular如何移除它们的信息(如果它实际上)。谢谢! – MrMalt