Communication between components:
So you started off by building individual components which would be self-sufficient and won’t depend on any other component for its data or information. Lets say you created a simple form which would allow you to save data or when editing, retrieve data. That’s all good but more often that not, in real world scenarios, you would be required to build components which talk to each other. Say one of your components received a user input and you need to notify all the components which deal with the same record so that they won’t show stale data. As discussed in my post about Lightning Data Services, if you’re using LDS then you don’t need to worry about this because LDS takes care of notifying the dependent components automatically. But there are times when you won’t be using LDS (LDS is yet to work for bulk records). How do you let your components talk to each other in such a situation? Enter Lightning Events!
Lightning components follow a Publisher-Subscriber model in order to communicate with each other via events. A publisher is a component that fires an event and a subscriber is a component that handles that event. Now both the publisher and subscriber need to let the framework know that they are gonna use this particular event for communicating. So the publisher needs to register the event in its markup before it can fire that event and a subscriber needs to register a handler to handle that particular event. This way the system knows who is gonna talk to whom and via which event. As is obvious, a publisher needs at least one subscriber and vice versa.
Types of events:
The lightning framework currently supports 3 types of events. These 3 types are used in different situations depending on the need but they all still stick to the publisher-subscriber model.
These are pretty straight-forward events and are available out of the box. For example, the init event. Some of them are fired by the system automatically and you can simply choose to handle them or not. Others, can be fired by you depending on the need. e.g. e.force:refreshView
These events are not limited by the containment hierarchy
I am pretty sure you must be quite curious by now as to what is the containment hierarchy? You might not even find this term in the standard salesforce documentation. However, I believe this what explains the scenario in a much better way. Let me start with an analogy.
I believe you all must have seen the famous Hollywood movie The Inception. If you haven’t then you must be living under a rock. Remember how Cobb would go 3 levels deep into the world of dreams? And that you cannot simply come out of the dream from level 3 without passing through level 2 and then level 1? Get the idea? That’s containment hierarchy.
Another decent analogy would be the Matryoshka dolls aka the Russian dolls!
The idea is that the source of the event (the component firing the event) lies contained within a hierarchy of containers (components) and upon firing, the event would have to pass through these individual containers to reach the top most container. This is more relevant for the component events. This movement of event is also known as propagation. This defines the sequence in which the event can be handled. The inner most container will be the first one to handle the event while the top most container will be the last one to handle it. This sequence can be reversed a well. To explain things better we need to know about Phase.
Phase is something that determines the order of event handling by the different containers. Depending on the type of the phase, the event can be handled starting from the innermost container or the outermost container. There are 3 types of phases.
If you have ever worked in an event-driven framework (like ASP.NET) you would be aware of the term event-bubbling. In this phase the event would travel like a bubble in a liquid. From bottom towards the top or from the innermost container to the outermost container. This is the default phase of events unless specified otherwise. The event propagation can be stopped by invoking event.stopPropagation(). Calling event.preventDefault() would stop execution of any of the handlers in the default phase. This phase applies to component events by default.
This phase is the reverse of the bubble phase. When an event is fired, the outermost container will be the first one to handle it and all the subsequent containers will handle it moving towards the innermost container. This phase needs to be mentioned specifically otherwise the default is the bubble phase. event.stopPropagation() and event.preventDefault() apply for this phase as well.
This phase occurs after the initial capture and bubble phases have occurred. This phase invokes the event handlers in a non-deterministic way starting from the topmost container or the application root and propagating through the various sub-trees of the application structure. Now, the topmost container or the application root can change if any of the components in the earlier phases invoked event.stopPropagation(). In that case, the component stopping the propagation would become the topmost container or the application root. This phase applies to application events by default.
Thats it! This should be enough for you to understand lightning events in theory. For hands on experience, I will write my next post. Keep reading!