Lightning components are designed to be self-contained and independent. While this is great for modular development and encapsulation, it comes at a price. That price is JavaScript. JavaScript from one component can’t talk with another, and that’s why Lightning components use events. Events handle any interaction that needs to take place between components: button clicks, modals, etc.
Events are a twofold process: sending and receiving. The sending component (and controller) creates and then fires the event. The receiving component (and controller) intercepts and handles it.
Want to know more about how it works? Before we talk examples, it’s important to note that Lightning component events can be one of two types: component and application.
The example below is a component event. Here’s the component design used in the examples below:
Event Types
- Component events are parent-child relationships, in which an event registered in the child component can be handled only by the parent and not other sibling components.
- Application events, on the other hand, are for sibling relationships. They can communicate with any other component. The type of component is determined by the event file itself by setting the attribute on the <aura:event> tag to either COMPONENT or APPLICATION.
Example Events
productAddItem.evt products.cmp productsController.js productForm.cmp productFormController.js
productAddItem.evt
<aura:event type="COMPONENT"> <aura:attribute name="products" type="Products__c" /> </aura:event>
Events are defined as separate entities from components and controllers, and they act as the go-between for the sending and receiving parties. The event definition also determines the event type: COMPONENT or APPLICATION.
productForm.cmp
<aura:component> <aura:attribute name="products" type="Products__c" /> <aura:registerEvent name="addProduct" type="c:productAddItem" /> <!—component form here—> <ui:button label="Add Product" press="{!c.clickAddProduct}" /> </aura:component>
While stripped down to the essentials for illustration purposes, this form component has a submit button attached to the event. The component registers an event (registerEvent is your cue this is the sending component) named addProduct. Keep this name in mind, because the receiving component will call this same name. It’s the glue that binds the sender and receiver together. The button references the clickAddProduct function in its controller, which begins the event process.
productFormController.js
({ clickAddProduct: function(component, event, helper) { var products = component.get(“v.products"); var createEvent = component.getEvent(“addProduct"); createEvent.setParams({“products" : products}); createEvent.fire(); } })
When the button in the above component is pressed, it sends the action off to this function in the controller. Validation aside, this is pretty simple. It “loads” the event and then fires it.
products.cmp
<aura:component> <aura:attribute name=“products" type=“Products__c[]"/> <aura:handler name="addProduct" event="c:productAddItem" action="{!c.handleAddProduct}" /> <c:productForm /> <!—rest of component stuff here—> </aura:component>
Just like we registered the event in the child component, we now handle it in the parent component with a handler. Note that the name, addProduct, is the same as when we registered the event. The action attribute defines the next step in the loop, which calls a function in the controller called handleAddProduct.
productsController.js
({ handleAddProduct: function(component, event, helper) { var newProduct = event.getParam(“products"); var action = component.get("c.saveProduct"); action.setCallback(this, function(response) { var state = response.getState(); if (component.isValid() && state === "SUCCESS") { component.set("v.products", response.getReturnValue()); } else { console.log("Failed with state: " + state); } }); $A.enqueueAction(action); } })
This is the receiving controller that handles the incoming event and communicates with the apex controller. The function, saveProduct, is a reference to the apex controller in which the upsert takes place (not shown here). The final line of code queues up the action (the call to the server), which upserts the form entry. And with that, the event cycle is complete.