[SalesForce] Lightning Components: Call init method of a child component from a parent component

I want to call the init method of a child LC from a parent LC.

I tried to use aura:method, and call the init method from a parent method.

.....
            <aura:attribute name="userContact" type="Contact" />

            <aura:method name="callInit" action="{!c.init}" >
            <aura:registerEvent name="appEvent" type="c:ET_AppEvent_OverNightStay"/>
            <aura:handler name="init" value="{! this }" action="{! c.init }"/>

            <lightning:layout multipleRows="false" >
                <lightning:layoutItem size="10">
                    </lightning:layoutItem> 
........

But it seems, that if I use (aura:method) I can't use (aura:registerEvent) and (lightning:layout) and many other tags!!

So my Qeustion:
How can I achieve this?


Just to clearify my problem, I have a parent component, and in this parent LC I have several Child LCs. It's like a path that user has to take.
this path is the following, when a user click on (event reservation) he has to fill the following (Select Contacts –> Select Events to attend –> Select Hotel and Room –> Summary&Confirm –> Confirmation Message)
There is a big parent then (book) parent then the 5 childs.

In General I'm using the (Lightning Inter-Component Communication Patterns)
– To send data from parent to child –> Attributes
– To send data from child to event –> Events

So when ever I'm switching to the next step (LC) the init method will be fired (but only once!).
So when I'm on the second step and select an event, then click next and fill the data of the hotel third step. If I click back to second step, and changed something and clicked next, the data from the second step, will not be noticed, since the init will not be fired again.

enter image description here

Best Answer

As you've mentioned above, if you are able to catch the tab switching activity in parent component and based on that call the aura:method, this should be working fine and should not give you problem of aura:registerEvent and other tags not rendering.

Approach 1

Recommended as this will not require lot of code re-structuring and work with your existing implementation:

Continue with your existing implementation and find out syntax issue if any.

Approach 2:

Use Renderer that calls same code as init():

afterRender: function (component, helper) {
    this.superAfterRender();
    helper.doInit(); //call required JS code or do DOM manipulation if required.
},
  • Move your init code in a helper method. Call this helper ,method from afterRenderer() in renderer file of lightning component bundle.

  • This way, you won't need to call init() explicitly using aura:method and everytime the component is rendered, your required code would be called.

  • Cons: afterRenderer() may be called multiple times if any DOM is changed causing unnecessary execution of code. This will then require to add logic to avoid the code repetition.

Approach 3:

Inheritance in lightning components

<!--c:super-->
<aura:component extensible="true">
    <aura:attribute name="state" type="String" default="Default description" />
    <!-- add a component event handler here -->
    <aura:handler name="cmpEvent" event="c:ceEvent" action="{!c.updateState}" />
</aura:component>

<!--c:sub-->
<aura:component extends="c:super">
    <!-- Throw event to super component with updated state as parameter.-->
    <aura:registerEvent name="cmpEvent" type="c:ceEvent"/> 
    <p>State at any time: {!v.state}</p>
</aura:component>
  • Maintain a "super" component that will be inherited by all child components. This "super" component can be the main parent component. It will have an attribute say "state" that will maintain all information required by all child components at any point of time. This information will be in JSON format.
  • All child components will have to update this attribute every time anything inside them changes(Say an event is added as per above example).
  • Thus, this state will be the updated state of all information to which any other child component can refer to at any time.