2017-10-11 79 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