Introduction
In this post, I am going to explain lightning component attributes. Component attributes are like member variables on a class in Apex. Lightning component attributes are used to exchange data between components. They have typed fields that are set on a specific instance of a component and can be referenced from within the component’s markup using an expression syntax. .Use the <aura:attribute> tag to add an attribute to the component or app. All attributes have a name and a type. Attributes may be marked as required by specifying required=”true”, and may also specify a default value. Let’s look at the following sample where I have defined two attributes of type String, Integer.
<aura:component>
<aura:attribute name="strAttribute" type="String"/>
<aura:attribute name="intAttribute" type="Integer" required="true" default="0"/>
<ui:button aura:id="button" press="{!c.increment}" label="{!v.intAttribute ? v.intAttribute : 0}"/>
</aura:component>
({
increment : function(c,e,h){
var prev = c.get("v.intAttribute");
c.set("v.intAttribute", prev ? prev+1 : 1);
}
})
From the above example
-
All attributes have a name and a type. Attributes may be marked as required by specifying required=”true”, and may also specify a default value.
<aura:attribute name="intAttribute" type="Integer" required="true" default="0"/
- Must begin with a letter or an underscore
- Must contain only alphanumeric or underscore characters
- You can set default values
- Make it as required
- You can access the attributes by using the {!expression} syntax .for example {!v.intAttribute} allow you to access the intAttribute attribute .
Now, let’s go deep into the different types of attributes and how we will be able to use them in the lightning components.
Basic Attributes Type
The component supports different types of attributes basic types like Boolean, Integer, String, Number etc and Object type and Complex types like functions and Facets. Here are the supported basic type values. Some of these types correspond to the wrapper objects for primitives in the apex.
<aura:component>
<aura:attribute name="typeBoolean" type="Boolean" default="false"/>
<aura:attribute name="typeDate" type="Date" default="2013-03-06T10:17:36.789Z"/>
<aura:attribute name="typeDateTime" type="DateTime" default="123456789" />
<aura:attribute name="typeDecimal" type="Decimal" default="122.62" />
<aura:attribute name="typeDouble" type="Double" default="12.1"/>
<aura:attribute name="typeLong" type="Long" default="123"/>
<aura:attribute name="typeMap" type="Map" default="{ a: 1, b: 2 }"/>
<aura:attribute name="typeInteger" type="Integer" default="1"/>
<aura:attribute name="typeString" type="String" default="welcome to salesforce"/>
Boolean - {!v.typeBoolean} <br/>
Date - {!v.typeDate}<br/>
DateTine - {!v.typeDateTime}<br/>
</aura:component>
Once you define the attributes you can able to access by using {!v.<attribute>} expression syntax as shown below.
<aura:attribute name="number" type="String" default="100000"/>
<ui:inputNumber label="Number" value="{!v.number}"/>
Function Type
An attribute can have a type corresponding to a JavaScript function. If a child component has an attribute of this type, you can pass a callback from a parent component that contains the child component. You will be able to use function type when you’re returning the asynchronous data from the aura:method callbacks.
<aura:attribute name="callback" type="Function" />
In the below example, The echo aura:method has an aura:attribute with a name of the callback. This attribute enables you to set a callback that’s invoked by the aura:method after execution of the server-side action.
<aura:method name="echo"
description="Sample method with server-side call">
<aura:attribute name="callback" type="Function" />
</aura:method>
var params = event.getParam('arguments');
var callback;
if (params) {
callback = params.callback;
}
'// Check the aura action status
if action is success then return the callback
if (callback) callback(response.getReturnValue());
An attribute can have a type corresponding to an Object. For example:
<aura:attribute name="data" type="Object" />
Salesforce recommends using type=”Map” instead of type=”Object” to avoid some deserialization issues on the server. You could able to iterate the object as shown below.
<aura:attribute name="data" type="Object"/>
<aura:iteration items="{!v.data}" var="item">
{!item.fieldName} -- {!item.newValue} <br/>
</aura:iteration>
Collection Types
An attribute can have a type corresponding to like the set, list or Map. you can use aura:iteration to iterate over the collections.
<aura:attribute name="typeList" type="List" default="[1,2,3]"/>
<aura:attribute name="typeStringList" type="String[]" default="['red','green','blue']" />
<aura:attribute name="typeMapList" type="Map[]"/>
<aura:attribute name="typeSet" type="Set" default="[1,2,3]"/>
<aura:attribute name="typeObject" type="Object" default="['red','green','blue']"/>
Map - {!v.typeMap}<br/>
Set - {!v.typeSet[0]}<br/>
List - {!v.typeList[0]}<br/>
Object - {!v.typeObject}<br/>
Custom Apex types
An attribute can have a type corresponding apex wrapper class as an attribute type.
public class ApexClassType {
@AuraEnabled
public String message{get;set;}
@AuraEnabled
public String warning{get;set;}
}
You will be able to refer the apex class as attribute as shown below.
<aura:attribute name="wrapper" type="ApexClassType"/>
Facet Types
A facet is an attribute of type Aura.Component[]. The body attribute is an example of a facet. in this example, I defined two Aura.component[] attributes which are passed when the component is instantiated. FacetDef component contains the title and footer attributes that are passed when components are instantiated from the FacetWrapper component.
FacetDef.cmp
<aura:component >
<aura:attribute name="title" type="Aura.component[]" />
<aura:attribute name="footer" type="Aura.component[]"/>
<section>
<div><span></span>{!v.title}</div>
<div><span> </span>{!v.body}</div>
<div><span></span>{!v.footer}</div>
</section>
</aura:component>
FacetWrapper.cmp
<aura:component >
<c:FacetDef aura:id="f1">
<aura:set attribute="title">
<ui:outputText value="Salesforce Lightning Component Title "/>
</aura:set>
<aura:set attribute="body">
<ui:outputText value="Salesforce Lightning Component Body"/>
</aura:set>
<aura:set attribute="footer">
<p> Copyright 2017 @{!v.org.Name} - {!v.org.Street} , {!v.org.City} ,{!v.org.State} ,{!v.org.Country} </p>
</aura:set>
</c:FacetDef>
</aura:component>
Aura Action Types
An Aura.Action is a reference to an action in the framework. If a child component has an Aura.Action attribute, a parent component can pass in an action handler when it instantiates the child component in its markup. This pattern is a shortcut to pass a controller action from a parent component to a child component that it contains and is used for on*handlers, such as onclick.
AuraAction.cmp
<aura:component>
<aura:attribute name="pressButton" type="Aura.Action" required="true"/>
<aura:attribute name="pressDiv" type="Aura.Action" required="true"/>
<ui:button aura:id="theButton" label="Press Me" press="{!v.pressButton}"/>
<div aura:id="theDiv" onclick="{!v.pressDiv}">Click Me</div>
</aura:component>
Invoke.cmp
aura:component>
<aura:attribute name="push" type="Boolean" default="false"/>
<div aura:id="displayResult">No action has run yet</div>
<c:AuraAction aura:id="fixture" pressButton="{!c.pressButton}" pressDiv="{!c.pressDiv}"/>
</aura:component>
({
pressDiv: function(cmp, event) {
var div = cmp.find("displayResult");
if (div) {
div.getElement().innerHTML = "Div Action is Presed";
}
},
pressButton: function(cmp, event) {
var div = cmp.find("displayResult");
if (div) {
div.getElement().innerHTML = "Button Action is Pressed";
}
},
})
Inheritance
A subcomponent that extends a super component inherits the attributes of the super component. Attribute values are identical at any level of extension. There is an exception to this rule for the body attribute, which we’ll look at more closely soon. In this example, I defined an attribute with name parentStr on the parent component. when child component extends the parent component it will inherit the parentStr attribute form the parent component without defining it again same as like apex or java.
Parent.cmp
<aura:component extensible="true">
<aura:attribute name="parentStr" type="String" default="Parent Component Description" />
{!v.parentStr}
</aura:component>
SubCmp.cmp
<aura:component extends="c:Parent">
<p>sub.cmp description: {!v.description}</p>
</aura:component>
when child component extends the parent component it will inherit the parent component attribute as shown above.
Interface
Other OOP programming like Java, Apex etc lightning component has Object-oriented support to define the interface that defines a set of signatures. the below example contains the set of attributes which you could use when you implement this interface.
<aura:interface >
<aura:attribute name="instanceId" type="Integer" default="-1"/>
<aura:attribute name="alias" type="String" default="panel2"/>
<aura:attribute name="title" type="String" default="Default Title"/>
<aura:attribute name="visible" type="Boolean" default="false"/>
<aura:attribute name="active" type="Boolean" default="false"/>
</aura:interface>
when a component implements an interface all attributes, methods, and events will be available by the compiler in the background, so the attributes will be available at runtime – say no need to really ‘implement’ from the interface by yourself as shown below.
<aura:component implements="c:panelType">
<div class="{!(v.visible ? 'visible' : '') + (v.active ? ' active' : '')}">
<p>{!v.title}</p>
</div>
</aura:component>