SFDC Stop - Always the latest about Salesforce


Full Tutorial Series with videos, free apps, live sessions, salesforce consulting and much more.


Telegram logo   Join our Telegram Channel

Sunday 23 December 2018

Salesforce Lightning Events Part 7 - Phases of Application Events

This blog is in continuation to my previous blog post, so if you haven't read the previous blog click here to read that first so that you're aware of the basics as in this post we're going to make some minor changes and learn more about the functionality and how different phases are working in case of application events.

Bubble and Capture Phases

Bubble and Capture phases are same in application events also as they were in case of component events. There is a 3rd phase also in case of application events which is known as Default Phase. So, let's learn about bubble and capture phases first:-

If you look at the code which is described in the previous post, I have made two handlers for my application event named LightningApplicationEvent in which one handler is in LightningAppComp1 component and other handler is in LightningEventsAppContainer component. Both the handlers are initially working in the bubble phase.

Just for a refresh I am going to explain briefly the components we've built. Below is the application event named - LightningApplicationEvent that we're using:-

Let's have a look at LightningAppComp1 first,

As you can see in the above code, I have registered the application event using the register event tag. But, this is important only in case of component events. In case of application events, this tag is not necessary as we don't refer to the application event using the name given in this tag, application events are global and we refer to those using the actual name of application event which is LightningApplicationEvent in this case. This concept will be more clear to you once we move on to the controller.

Apart from this, I have defined a handler for this event which is calling handleApplicationEvent method of our controller and is running in bubble phase and there is a button which is calling fireApplicationEvent method of our controller.

Moving on to the lightning controller for this component, let's have a look at the below code:-

As you can see above, in the fireApplicationEvent method, you can see that I am referring to the application event using $A.get("e.c:LightningApplicationEvent"); that's why we don't necessarily need a register tag for this as we get a reference to this event using the global aura $A variable in js. In the handleApplicationEvent method, I am simply showing an alert Application event in source component with the id which is passed from the parent component.

Now let's have a look at the parent component and associated controller.

As you can see in the above code, in the component I have made a handler for LightningApplicationEvent which is calling handleApplicationEvent method of it's associated controller and down below, I have called LightningAppComp1 in which I have passed the id attribute. Moving onto the controller now:-

As you can see above, in the controller code, I have only one method named handleApplicationEvent which is showing an alert message:- Application Event in container component  with the id attribute which is passed from application as this component is called twice from application. You can view the application code here. So, after showing the alert, I am simply setting the message attribute using component.set as I have displayed it in this parent component.

Now we'll be dealing with above 4 code snippets i.e. two components to deal with each phase. Before moving to each phase separately some points to remember:-
  1. A phase is always associated with the event handler.
  2. If you haven't specified any phase in handler, the default phase will be applied automatically in case of application events.
  3. If you have event handlers in all the bubble, capture and default phase, the order of execution is Capture->Bubble->Default.

Bubble Phase

Initially as you can see in the code, the event handlers in source and parent component are working in bubble phase. In this phase, the event propagates from source to parent component, so as we fire the event by clicking the button in source component, first it's handler will fire and you'll see an alert showing:- Application event in source component appended with the id.

As you can see in the  below output, I have called my parent component twice with id 1 and 2 in application and clicked on the fire event button of the source component within the parent with id 1.


Followed by this you'll have another alert showing:- Application Event in container component appended with id.


Then the message will be set in the container component which is received from the event.


As you can see here, the message in the parent component is set to hello which was sent by my source component when the event was fired and another thing to notice is that only the first call to parent component is affected by the event not the second one with id 2. However, we know that the same source component is called from both instances of parent component and event is traversing from source to root still the event know which path to follow or we can say that the source component is also copied twice with parent as it is called twice with different ids in application. So, by this we can conclude that Application Events behave similar to Component Events in Bubble phase.

Capture Phase

To execute the handlers in this phase, just change the phase attribute in both the source and parent component handlers to capture. You can view the change in both components below:-

LightningEventsAppContainer.cmp


LightningAppComp1.cmp

Now, as you can see in the below output, this time I have clicked on the button present in the source component which is called from the second call to parent component in application, i.e. the id passed is 2. Both the handlers are working in the capture phase. In this phase, the event follows a top-bottom approach i.e. starting from the application root to the source component. 



As you can see above, first of all the alert in parent component is called with id 2. Following this, the alert in source component will be called with id 2 as shown in the below output.



And finally the message will be set in the parent component with id 2 actually, it was set before when the event is handled but the we see it later because component.set() is taking time to work and within that span another alert was called. JavaScript is too fast..!! :P



If you remember the applications code, same parent component is called twice with id 1 and 2 and we've called the source component from the parent component and we know that the capture event traverse from application root to bottom, therefore, we can assume that it should move to both the parent component and then to child component. But in this case too application event knows which path to follow and it follows the path only to the particular copy of source component which was responsible for firing the event. So, by this we can conclude that Application Events behave similar to Component Events in Capture phase too.

Default Phase

In this phase, event handlers are called starting from the application root traversing the sub-tree i.e. all the components that are present in each level while moving down towards the source component that fired the event. To test in this phase, just remove the phase attribute from both the handlers because by default the application events are handled in the default phase. You can view the change in both components below:-

LightningEventsAppContainer.cmp

LightningAppComp1.cmp

Default Phase is very different as compared to the bubble and capture phases.

In default phase, the application event starts from the application root and all the handlers are executed following a bottom up fashion in each sub tree considering the application root as the root node.

Below is the diagram stating the sample application using which we're trying to understand application events. As we have a lightning application which is calling two components i.e. the same component with different id 1 and 2 and these components are again calling the source component in their body.

As we can see the event fired is specified by blue arrow and it is moved towards the application root. Then, the event is moved to first sub tree and is handled in a bottom-up fashion and then it is moved towards second sub tree and is handled again in the bottom up fashion. the component 3 i.e. the root component is handling event twice as different copy of component 3 is made and used for each parent component called by the application.Then, the event is handled by the application root if any handler is present there. Since in our case, there is no handler defined in application, so no event is handled.



Similarly, we can see the output below:-

I am clicking the fire event button in first parent and I have the alert as below:-



And then the application event is moved to it's parent while traversing the first sub tree. So, we have:-



Then the application event is moved towards the second sub tree and are traversed in a bottom up fashion. Therefore, first we have the alert from root again but the id is 2.



And then, the event is moved towards the parent in second sub tree and handled there.



After all the alerts, you'll see that the text is changed in both the parent components as shown below:-


Now your task is to create a handler for this application event in the application root and notice how many times it's called. You'll see that even if the event is going towards each sub tree one by one still it's called only once in the application root after traversing all the subtrees.

Points to Remember:-

1.  The default phase usually occur after the capture and bubble phases in the order of execution and will not occur if you call event.preventDefault(); while handling the event in any of the capture or bubble phases.

2. If event.stopPropagation(); is called in the capture phase, no event is called further in the capture phase or in bubble phase and if it is called in bubble phase, no event is called further in this phase. Same concept as component event.

3. If event.stopPropagation(); is called by any handler before the default phase that component consisting of the handler in which this method is called becomes the root node for the default phase.

4. event.stopPropagation(); doesn't affect if it's called in any handler handling the event in default phase.

Try the 3rd point on your own and let me know if you face any difficulties understanding it in the comments section below.

Tired of reading or just scrolled down..?? Don't worry, you can watch the video too :-)



This was my last blog in Lightning Events Tutorial Series. I hope you liked this post. Do share it in your network and keep learning. Thanks for reading.

Happy Trailblazing..!!

No comments:

Post a Comment