This post presents the specificities of Lightning component events (in opposition to application events). This event type is the most commonly used in the Lightning Component framework; yet, it’s also the most complex. Few Lightning developers know all of its “secrets.”
This article is a follow up of the Lightning Inter-Component Communication Patterns post. If you have not read it yet, read it first as it covers the basics of firing and handling events.
DOM event propagation basics
Before we get into the details of component events propagation, let’s first have a quick refresher on standard DOM event propagation. Forget the Lightning Component framework for a moment; we’re talking about standard HTML in this section.
DOM events follow two consecutive propagation phases that developers can follow: capture (rarely used) and bubble (widely used). Events first go down the DOM tree during the capture phase, then up during the bubble phase. The capture phase always executes before the bubble phase.
The diagram illustrates the two event propagation phases that occur along the DOM tree after a user clicks a button in a form. Notice that the event propagation does not originate from the button itself.
If you want to learn more on this subject, here’s a great article on DOM event propagation. But let’s get back to the Lightning Component framework for now.
Component event propagation
Handling an event in a specific phase
Lightning component events also support both capture and bubble phases, but there are some framework specificities in terms of syntax and behavior.
By default, component events are handled in the bubble phase, and that’s what most developers use.
To handle the capture phase, add a phase="capture"
attribute to your event handler, like so:
Note that you can declare two handlers for the same event if you wish to handle both phases (one for bubble and one for capture).
You can query the event’s current propagation phase by calling event.getPhase()
in your event handling function. This function returns either capture
or bubble
.
Propagating to Container components
There’s a major difference between component events and DOM events: the way they propagate to containers.
To summarize, and as stated in the component event documentation:
By default, every parent in the containment hierarchy can’t handle an event during the capture and bubble phases. Instead, the event propagates to every owner in the containment hierarchy.
To put it simply: A Lightning component hierarchy does not behave like a DOM tree. By default (we get to the exceptions later), only parent components that create subcomponents (either in their markup or programmatically) can handle events. This singles out container components.
A container is a component that supports embedding subcomponents. In HTML, most elements are containers (for instance, a div
or a span
). In the Lightning Component framework, containers are components that expose one or more attribute of type Aura.Component[]
such as the default body
attribute.
For example, this code presents a containerCmp
component:
containerCmp
is a container since it exposes its body
attribute in a {!v.body}
expression. This implies that containerCmp
can be used by a parent component parentCmp
as shown here:
By default, containers cannot handle events thrown by components they contain. That’s so because container components are not considered owners of events that they encapsulate.
Let’s extend the previous example by adding an eventEmitterCmp
component embedded inside containerCmp
:
If eventEmitterCmp
fires a component event, containerCmp
cannot handle it by default, but parentCmp
can.
If you want a container component to handle a component event, add an includeFacets="true"
attribute to its handler, such as:
Stopping Event Propagation
Just like for standard DOM events, the propagation of component events can be stopped to prevent other components from handling an event.
Calling event.stopPropagation()
stops the event propagation regardless of the current propagation phase.
As a best practice, do not stop event propagation unless you have a particular reason to do so. Leaving the event to propagate itself allows you to extend your application by adding event handlers in other components.
Pausing and Resuming Event Propagation
Unlike DOM events, component event propagation can be paused with event.pause()
and resumed with event.resume()
. The typical use case for this is asynchronous processing.
For example, the event handler’s code:
- Pauses a component event
- Calls a server-side action
- Then, the action callback resumes or stops the event propagation based on the server response
Closing words
You now know about the two event propagation phases: capture and bubble. You saw an overview of the subtleties of component events: event handling in container components and event propagation control functions (pausing, resuming, and stopping).
How about experiencing all of what you’ve learned in the interactive Lightning Component Playground App? Feel free to explore the different event functionalities and the source code.
Learn more on the Lightning Component framework by practicing with the Lightning Components Basics Trailhead module.