We have been using below two techniques to communicate from parent to child. In addition to the below techniques, introducing advance way of communication with the component body technique.
Component Body
The root-level tag of every component is <aura:component>. Every component inherits the body attribute from <aura:component>. We dont need to create a separate attribute to handle the v.body.
Any free markup that is not enclosed in one of the tags allowed in a component is assumed to be part of the body and is set in the body attribute.
The body attribute has type Aura.Component[]. It can be an array of one component, or an empty array, but it's always an array.
In a component, use “v” to access the collection of attributes. For example, {!v.body} outputs the body of the component.
Below is the perfect example for body communication technique. Follow the step by step process to see the end result. Its gonna be very advanced level of communication technique.
===========
Step 1: Markup : Coldata (below component just acts like a programmatic abstraction, it wont display any data). Sole purpose of the below component is to pass the data to the Childcmp.
=========
<aura:component >
<aura:attribute name="Firstname" type="string" />
<aura:attribute name="LastName" type="string" />
<aura:attribute name="age" type="Integer" />
</aura:component>
==========
Step 2: Markup :Coldata2 (Again below component also just acts like a programmatic abstraction, it wont display any data). Sole purpose of the below component is to pass the data to the Childcmp.
=========
<aura:component >
<aura:attribute name="att1" type="string" />
<aura:attribute name="att2" type="string" />
</aura:component>
=========
Step 3: Markup :Childcmp
=========
<aura:component >
<aura:attribute name="subtagsdata" type="object[]" />
<aura:attribute name="subtagsdata2" type="object[]" />
<aura:handler name="init" value="{!this}" action="{!c.doinit}" />
{!v.body} <!---without this attribute you would not be able to access the body placed in the below parent component(see step 5) -->
<table border="1">
<tr>
<th>FirstName</th>
<th>LastName</th>
<th>Age</th>
</tr>
<aura:iteration items="{!v.subtagsdata}" var="item">
<tr>
<td> {!item.Fname} </td>
<td> {!item.Lname} </td>
<td> {!item.age} </td>
</tr>
</aura:iteration>
</table>
</aura:component>
========
Step 4: JavaScript controller:Childcmp
========
({
doinit : function(component, event, helper) {
var body=component.get("v.body");
var coldata=[];
var coldata2=[];
for(var i=0; i<body.length;i++){
/* below code differentiates two different components instances */
if(body[i].isInstanceOf("c:Coldata")){
coldata.push(
{
Fname:body[i].get('v.Firstname'),
Lname:body[i].get('v.LastName'),
age:body[i].get('v.age')
}
);} else{
coldata2.push(
{
att1:body[i].get('v.att1'),
att2:body[i].get('v.att2')
}
);
}
}
component.set('v.subtagsdata',coldata);
component.set('v.subtagsdata2',coldata2);
console.log('%%%%Col data 1%%%%'+JSON.stringify(component.get('v.subtagsdata')));
console.log('%%%%Col data 2%%%%'+JSON.stringify(component.get('v.subtagsdata2')));
}
})
=============
Step 5: Markup : Parentcmp
=============
<aura:component >
<aura:attribute name="fn" type="string" default="Oliva trainings"/>
<c:Childcmp >
<c:Coldata Firstname="Dave" LastName="Oliva" age="28" />
<c:Coldata Firstname="Dave1" LastName="Oliva1" age="29" />
<c:Coldata Firstname="Dave2" LastName="Oliva2" age="30" />
<c:Coldata Firstname="Dave3" LastName="Oliva3" age="31" />
<c:Coldata2 att1="col2dataatt1" att2="col2dataatt2" />
<c:Coldata2 att1="col2dataatt1" att2="col2dataatt2" />
</c:Childcmp>
</aura:component>
=========
Step 6: Markup :Bodycommunication
=========
<aura:application >
<c:Parentcmp />
</aura:application>
Final output looks as below.