I have done a simple component which display contacts list which involves two components
1.ContactList - Parent (Fetches the contact details)
2.ContactListItem - Child (Display individual contact detail)
Component Level Event is used to carry the contact from ContactListItem to ContactList which holds the source contact array where contact removal is done.
ContactList.cmp
<aura:component access="public" controller="ContactController">
<aura:attribute name="contacts" type="Contact[]" access="private"/>
<aura:handler name="init" action="{!c.doInit}" value="{!this}" />
<aura:handler name="deleteContact" event="c:deleteContactEvt" action="{!c.removeContact}" />
<table class="borderCls">
<tr>
<th class="borderCls">Name</th>
<th class="borderCls">Phone</th>
</tr>
<aura:iteration items="{!v.contacts}" var="contact">
<c:ContactListItem contactRec="{!contact}"/>
</aura:iteration>
</table>
<button onclick="{!c.addContact}">Add Contact</button>
</aura:component>
ContactListController.js
({
doInit : function(component, event, helper) {
var action = component.get("c.getContacts");
action.setCallback(this, function(data) {
console.log(data.getReturnValue());
component.set("v.contacts", data.getReturnValue());
});
$A.enqueueAction(action);
}
,
addContact : function(component, event, helper){
var contacts = component.get("v.contacts");
var len = contacts.length;
contacts.push({
'Name':'Test Contact - '+len,
'Phone':'123'+len
'sobjectType':'contact'
});
component.set("v.contacts",contacts);
}
,
removeContact : function(component, event, helper){
var selCont = event.getParam("selectedContact");
var contacts = component.get("v.contacts")
var index = contacts.indexOf(selCont);
if (index > -1) {
contacts.splice(index, 1);
}
component.set("v.contacts",contacts);
}
})
ContactListItem.cmp
<aura:component >
<aura:attribute name="contactRec" type="Contact" access="public"/>
<aura:registerEvent name="deleteContact" type="c:deleteContactEvt"/>
<tr >
<td class="borderCls" >{!v.contactRec.Name}</td>
<td class="borderCls" >{!v.contactRec.Phone}</td>
<td> <ui:button label="Delete" press="{!c.deleteContact}"/></td>
</tr>
</aura:component>
ContactListItemController.js
({
deleteContact : function(component, event, helper) {
var event = component.getEvent("deleteContact");
event.setParams({
'selectedContact':component.get("v.contactRec")
});
event.fire();
}
})
deleteContactEvt.evt (Component Level Event)
<aura:event type="COMPONENT" description="Delete Contact Event">
<aura:attribute name="selectedContact" type="Contact"/>
</aura:event>
ApexController
public class ContactController {
@AuraEnabled
public static List<Contact> getContacts() {
return [Select Id, Name, Birthdate, AccountId, Account.Name, Email, Title, Phone
From Contact order by LastModifiedDate desc
limit 10];
}
}
I Hope this helps
Best Answer
It's kind of a judgemental call. Basically, there are 2 ways to show hide markup.
Option 1: Using CSS show/hide. This basically means you would use a CSS class to hide the elements in UI but the HTML Markup, attributes will still exist in your DOM(Document object model). In plain technical CSS terms you would add a class property:
display: none;
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_cb_show_hide_markup.htmThe advantage of this approach is that if you are basically going to hide 1 or 2 markup elements there is no point in using an
aura:if
and writing some logic to show/hide it as it will destroy the element and re-create it based on conditions. In CSS show/hide it will just be hidden from UIOption 2: Using
aura:if
The use case for this would be let's say you are showing a 3 to 5 step wizard navigation. Basically, like payment cart, you wouldn't want to keep all steps in your component hidden using CSS as the DOM can get quite heavy if each step is going to have like 10 fields and you can never say the user is going to scroll through all 5 steps always. In this case, there is no point in loading all 5 steps together. It's better to lazy load them as and when it's needed. This is a perfect use case foraura:if
. Below markup illustrates that and you load each step when the user clicks next button by setting the attribute 'step' as shown belowThis could kind of like a design pattern that you can follow and put the server side controller in the container component which includes all these steps and just wire them up using events and
aura:methods
. So all server calls are delegated to server component and the individual data components just act as self-contained steps just taking care of their data and validations.Hope this helps. Let me know if you need more information.