9

I was looking at this blog post about Dynamically Instantiate and destroy Lightning Components – Modal dialog component and author is instantiating, destroying child component from the code.

But I was able to replicate similar output without doing all(instantiating and destroying from code) of that so curious about the whole concept of destroying components programmatically.

  1. Why do we need to destroy lightning components from the code?
  2. Don't lightning components get destroyed when user navigates to different url/page?
  3. I think destroying components is something similar to garbage collection in java but besides performance improvements or there are any functional bugs in my implementation below:

ExampleOne.app:

<aura:attribute name="input1" type="String"/>
<aura:attribute name="input2" type="String"/>

<div aura:id="parent-div-id">

    <div class="slds-form-element slds-size--1-of-6 slds-m-around--xx-small">
        <ui:inputText label="param 1" value="{!v.input1}"  class="slds-input"/>
    </div>
    <div class="slds-form-element slds-size--1-of-6 slds-m-around--xx-small">
        <ui:inputText label="param 2" value="{!v.input2}"  class="slds-input"/>
    </div>

    <div class="slds-size--1-of-6 slds-m-around--xx-large slds-clearfix">
        <ui:button label="Open Modal Dialog" 
                    press="{!c.openModal}" 
                    class="slds-button slds-button--destructive slds-float--right"  />
    </div>

    <!-- Modal for editing schedules -->
    <div role="dialog" id="child-modal" tabindex="-1" aria-labelledby="header44" class="slds-modal">
        <div class="slds-modal__container">
            <div class="slds-modal__content slds-p-around--medium">
                <div class="slds-form-element">
                    <c:ModalComponent aura:id="childCmp"/>
                </div>
            </div>
            <div class="slds-modal__footer">
                <button class="slds-button slds-button--neutral" onclick="{!c.closeModal}">Cancel</button>
            </div>
        </div>            
    </div>        

    <div id="modal-backdrop" class="slds-backdrop"></div>
</div>               

ExampleOneController.js:

({
    openModal : function(component, event, helper) {

        var schChildComp = component.find('childCmp');
        schChildComp.loadData(component.get('v.input1'),component.get('v.input2'));

        var rootElem = component.find('parent-div-id').getElement();

        var modalElem = rootElem.querySelector('#child-modal');
        modalElem.className = 'slds-modal slds-fade-in-open';
        var modalBackDropElem = rootElem.querySelector('#modal-backdrop');
        modalBackDropElem.className = 'slds-backdrop slds-backdrop--open';        
        return false;
    },
    closeModal : function(component){
        var rootElem = component.find('parent-div-id').getElement();

        var modalElem = rootElem.querySelector('#child-modal');
        modalElem.className = 'slds-modal';
        var modalBackFropElem = rootElem.querySelector('#modal-backdrop');
        modalBackFropElem.className = 'slds-backdrop'; 
    }
})

ModalComponent.cmp:

<aura:attribute name="arg1" type="String"></aura:attribute>
<aura:attribute name="arg2" type="String"></aura:attribute>

<aura:method name="loadData" action="{!c.loadData}"> 
    <aura:attribute name="p1" type="String"/>
    <aura:attribute name="p2" type="String"/>
</aura:method> 

Value 1 passed from parent: <aura:text value="{!v.arg1}"></aura:text><br/>
Value 2 passed from parent: <aura:text value="{!v.arg2}"></aura:text>

ModalComponentController.js:

({
    loadData : function(component, event, helper) {
        debugger;
        var params = event.getParam('arguments');
        component.set("v.arg1",params.p1);
        component.set("v.arg2",params.p2);
    }
})

Output:

enter image description here

NOTE: I am not seeing any lightning component related warnings in browser console.

6

The only time you need to call destroy explicitly is if you never add it to a body. If you do so, it will be destroyed automatically once removed. This is in the documentation:

Destroying Dynamically Created Components

After a component that is declared in markup is no longer in use, the framework automatically destroys it and frees up its memory.

If you create a component dynamically in JavaScript and that component isn't added to a facet (v.body or another attribute of type Aura.Component[]), you have to destroy it manually using Component.destroy() to avoid memory leaks.

So, in the general case, you don't ever need to call destroy, unless you never assigned it anywhere. The framework will clean up after you.

Q & A

Why do we need to destroy lightning components from the code?

You're not creating anything (there's no $A.createComponent), so no need to worry about destroying anything.

Don't lightning components get destroyed when user navigates to different url/page?

Yes, but they also get destroyed when they're no longer in the DOM anywhere. Remember that Lightning is a Single Page Application, and so the browser doesn't load/unload the page repeatedly. This provides a smoother user experience.

I think destroying components is something similar to garbage collection in java but besides performance improvements or there are any functional bugs in my implementation below

This implementation is just fine. The framework will create/destroy your components for you.

  • So in my case, I don't need to destroy component because it is in the markup and not injected from JS? – javanoob Jul 26 '17 at 0:29
  • 1
    @javanoob Yes, I was actually editing in more details to answer your sub-questions, but in summary, if you don't create it, you don't need to destroy it. – sfdcfox Jul 26 '17 at 0:30
  • @sfdcfox If we create a component dynamically and add to body, how to remove the component from body when we destroy the component using component.destroy(). ? – brahmaji tammana Mar 19 '18 at 8:01
  • I understand that framework destroys the component but the reference from body attribute is not getting updated. For example: length of body attribute is still showing the same as it is supposed to reduce on destroy. – brahmaji tammana Mar 19 '18 at 8:03
  • 1
    @brahmajitammana That's not how destroy works. You, the developer, must remove the component from the body if you set it there. Calling destroy on a component that is in use may have undesirable side effects, so don't do it. And, as stated in this answer, do not ever explicitly call destroy unless you never added the component to a body attribute. – sfdcfox Mar 19 '18 at 8:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.