lightning components workshop v2
TRANSCRIPT
Building Lightning ComponentsChristophe CoenraetsDeveloper Evangelist
#TrailheadLive@ccoenraets
http://developer.salesforce.com/trailhead/projects
What you will do
Build an Account Locator built as a a set of loosely coupled components communicating through events Explore different deployment options:• Lightning App• Salesforce1 App• App Builder Composition
AccountMap
AccountList
AccountLocator
AccountListItem
Step 1:Setting Up Your Environment
1. Sign up for a Developer Edition Org2. Enable My Domain3. Deploy to Users
Challenge
Step 2:Enabling Geolocation on Accounts
1. Add a geolocation field to the Account object2. Enter sample data
Challenge
Step 3:Creating an Aura-Enabled Controller
Visualforce Page-Centric Model
1. Browser requests page
Client Server
4. Browser renders html
2.Server executes Apex code3.Server returns page (html + data)
Show different data? Back to 1Show different view? Back to 1
Pros1. Proven model2. Productivity. Easy to implement3. Naturally splits large apps into small, manageable units (pages)
Caveats4. Limited interactivity5. Higher latency
Visualforce Page Centric Model
Lightning App-Centric Model
1. Browser requests Component
Client Server
3. Browser builds UI with JavaScript
4. Browser requests data
7. Back to 3
2.Server returns Component Bundle
5. Server executes Apex6.Server returns data (data only!)
Show different data? Back to 4Show different view? Back to 3
Pros• Enables highly interactive/immersive user experiences• Less page refreshes• Tightly integrated (no iframe)• Composable
Caveats• Higher learning curve compared to vanilla Visualforce pages• Higher level of complexity. Building an app is generally more complex than building a
page
Lightning Components App Centric Model
Creating an Aura-Enabled Apex Controller
public with sharing class AccountController {
@AuraEnabled public static List<Account> findAll() { return [SELECT id, name FROM Account]; }
}
* You should add code to enforce CRUD and FLS
1. Create an Aura-enabled Apex controller named AccountController
2. Add a findAll() method that returns accounts that have location information
Challenge
Step 4:Creating the AccountLocator
Component
Anatomy of a Lightning Component
<aura:component controller="AccountController">
<div>
<div>AccountMap goes here</div>
<div>AccountList goes here</div>
</div>
</aura:component>
Component Parts: Component
UI MarkupData bindingAttributes
Component
Component Parts: Style
UI MarkupData bindingAttributes
ComponentStyle
EncapsulatedCSS
1. In Lightning Applications2. In the Salesforce1 app3. In App Builder
Where can I use Lightning Components?
Using a Lightning Component in a Lightning App
1. Create a Lightning AppFile > New > Lightning Application
2. Embed the Lightning Component<aura:application>
<c:AccountLocator/>
</aura:application>
Useful for creating fullscreen apps or for testing components during development
Using a Lightning Component in the Salesforce1 App
1. Implement the force:appHostable interface<aura:component implements="force:appHostable">
2. Create a Tab3. Add the Tab to Mobile Navigation
1. Create the AccountLocator component2. Add AccountLocator to the Salesforce1 App menu
Challenge
Step 5:Creating the AccountList
Component
Attributes
• The data of the component• Available anywhere in the component• Examples:
<aura:attribute name="price" type="Number"/>
<aura:attribute name="title" type="String"/>
<aura:attribute name="account" type="Account"/><aura:attribute name="accounts" type="Account[]"/>
Data Binding {! }
<aura:attribute name="account" type="Account"/>
<p>{!v.account.Name}</p>
Initial value of <p> is set to the value of account.Name Value of <p> automatically updated when value of account.Name changes
Bidirectional Data Binding
<aura:attribute name="price" value="100" type="Number"/>
<ui:inputNumber label="Principal:" value="{!v.price}"/>
Initial value of inputNumber is set to value of attribute (100) Value of price attribute is updated when user types new value in inputNumber
Component Parts: Controller
UI MarkupData bindingAttributes
Component
EventHandlers
ControllerStyle
EncapsulatedCSS
<aura:attribute name="counter" type="Number" default="0"/><ui:button label="Click me" press="{!c.handleClick}"/><div>{!v.counter}</div>
handleClick: function(component, event) { var counter = component.get("v.counter"); counter = counter + 1; component.set("v.counter", counter);}
Com
pone
ntCo
ntro
ller
Event Handler ExampleCounter
Event Handler ExampleRetrieving Data on Init
<aura:attribute name="accounts" type="Accounts[]"/><aura:handler name="init" value="{!this}" action="{!c.doInit}" />
doInit : function(component, event) { var action = component.get("c.findAll"); action.setCallback(this, function(a) { component.set("v.accounts", a.getReturnValue()); }); $A.enqueueAction(action);}
Com
pone
ntCo
ntro
ller
Iterating through a List
<aura:attribute name="accounts" type="Account[]"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<ul>
<aura:iteration items="{!v.accounts}" var="account">
<li>{!account.Name}</li>
</aura:iteration>
</ul>
Nested Component
• A component used in another component• AccountListItem Example:<aura:component>
<aura:attribute name="account" type="Account"/>
<li>{!v.account.Name}</li>
</aura:component>
Using a Nested Component
<aura:attribute name="accounts" type="Account[]"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<ul>
<aura:iteration items="{!v.accounts}" var="account">
<c:AccountListItem account="{!account}"/>
</aura:iteration>
</ul>
1. Create the AccountList component responsible for displaying the list of accounts
2. Create the AccountListItem component that you nest inside AccountList to render individual accounts in the list
Challenge
Step 6:Creating the AccountMap Component
• External JavaScript libraries and CSS style sheets must be loaded as static resources
• Use the <ltng:require> tag to load them• Loading is asynchronous• afterScriptLoaded event is triggered after files have been succesfully
loaded
Loading External JavaScript Libraries and CSS Files
Loading External JavaScript Libraries
<ltng:require scripts="/resource/leaflet/leaflet.js"/>
Loading External CSS Style Sheets
<ltng:require styles="/resource/leaflet/leaflet.css" />
Loading JavaScript Libraries and CSS Style Sheets
<ltng:require scripts="/resource/leaflet/leaflet.js"
styles="/resource/leaflet/leaflet.css" />
Using the afterScriptLoaded Event
<ltng:require scripts="/resource/leaflet/leaflet.js" styles="/resource/leaflet/leaflet.css" afterScriptsLoaded="{!c.renderMap}" />
1. Load leaflet JS library2. Load Leaflet CSS3. Render the map when files are loaded
Challenge
Step 7:Intercomponent Communication
Intercomponent Communication
Application Event Broker
Event Object
<aura:handler event="c:AccountsLoaded" action="{!c.accountsLoadedHandler}"/>
<aura:registerEvent name="loaded" type="c:AccountsLoaded"/>
var event = $A.get("e.c:AccountsLoaded");event.setParams({"accounts": accounts});event.fire();
AccountMapAccountList
Creating the AccountsLoaded Event
<aura:event type="APPLICATION">
<aura:attribute name="accounts" Type="Account[]"/>
</aura:event>
1. Create the AccountsLoaded Event2. Trigger the AccountsLoaded Event in AccountList3. Handle the AccountsLoaded Event in AccountMap
Challenge
Step 8:Using Events to Center the Map
Intercomponent Communication
Application Event Broker
Event Object
<aura:handler event="c:AccountSelected" action="{!c.accountSelectedHandler}"/>
<aura:registerEvent name="select" type="c:AccountSelected"/>
var event = $A.get("e.c:AccountSelected");event.setParams({"account": account});event.fire();
AccountMapAccountList
1. Create the AccountSelected event2. Trigger the AccountSelected event in AccountList3. Handle the AccountSelected event in AccountMap and center the
map on the selected account location
Challenge
Step 9:Interacting with the Salesforce1 App
1. Lightning Components enable you to extend standard features2. Don't reinvent the wheel
For example, if your component needs an account details view: use the standard one, don't create your own
3. Navigation between standard features and custom components should be smooth and feel integrated: users shouldn't notice they are switching between standard and custom features
4. Platform events allow you to integrate your custom components into the standard experience
Salesforce1 Integration
Firing a Platform Event
var event = $A.get("e.force:navigateToSObject");
event.setParams({
"recordId": accountId
});
event.fire();
This event will be handled be the Salesforce1 app which will then navigate to the account's details view
Component Parts: Helper
UI MarkupData bindingAttributes
Component
EventHandlers
Controller
SharedLogic
HelperStyle
EncapsulatedCSS
When a user clicks a marker on the map, load the default Salesforce1 details view for the selected account
Challenge
Step 10:Using Components in App Builder
Using a Lightning Component in App Builder
1.Implement the flexipage:availableForAllPageTypes interface
<aura:component implements="flexipage:availableForAllPageTypes">
2.Create a component description in the Design part
<design:component label="AccountList">
</design:component>
3.Enable App Builder for Lightning Experience (PILOT)
4.Drag the component from the component palette in App Builder
Compose AccountList and AccountMap in App Builder
Challenge
Summary
UI MarkupData bindingAttributes
Component
Design Descriptor
EventHandlers
Controller
SharedLogic
HelperStyle
Custom Rendering
Renderer
EncapsulatedCSS
App Builder