2

So I was going through this Salesforce doc about event propagation rules: Handling Bubbled or Captured Component Events

What this doc says is that "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.

Now, who is the owner component? So if I have this setup (same what doc examples):

<!--c:owner-->
<aura:component>
    <c:container>
        <c:eventSource />
    </c:container>
</aura:component>

c:owner is the outermost component that's why it is a Parent component and can only handle the component level events fired by c:eventSource.

A note from doc: "c:container contains c:eventSource but it’s not the owner because it’s not the outermost component in the markup, so it can’t handle the bubbled event. c:owner is the owner because c:container is in its markup. c:owner can handle the event."

I thought to go ahead and try this in practice. What I noticed is that component event fired from c:eventSource is handled by both the components in the hierarchy. Here is the code.

eventSource.cmp

<aura:component description="eventSource" access="global">
    <aura:registerEvent name="compEvent" type="c:compEvent" />

    <div class="slds-grid slds-grid_align-center slds-p-vertical_large">
        <div>
            <lightning:button label="Fire Component Event"
                              name="componentevent"
                              onclick="{!c.fireComponentEvent}"
                              variant="brand"/>
        </div>
    </div>
</aura:component>

eventSourceController.js

({
    fireComponentEvent: function (component) {
        var cmpEvent = component.getEvent("compEvent");
        cmpEvent.fire();
    }
})

container.cmp

<aura:component description="container" access="global">
    <aura:handler name="compEvent" event="c:compEvent" action="{!c.handleComponentEvent}"/>

    <c:eventSource />
</aura:component>

containerController.js

({
    handleComponentEvent: function (component,event) {
        console.log("I am in container component");
    }
})

owner.cmp

<aura:component description="owner" access="global">
    <aura:handler name="compEvent" event="c:compEvent" action="{!c.handleComponentEvent}"/>

    <c:container/>
</aura:component>

ownerController.js

({
    handleComponentEvent: function (component,event) {
        console.log("I am in owner component");
    }
})

LightningApp.app

<aura:application extends="force:slds">
    <c:owner/>
</aura:application>

This is screen shot after I click the button. The c:container component should not catch the event during the Propagation cycle.

enter image description here

Am I missing something here in the understanding of the event propagation?

Thanks

1

There are some fundamental things to understand here :

The component event life cycle has three different stages

1.Event fired—A component event is fired.

2.Capture phase—The framework executes the capture phase from the application root to the source component until all components are traversed. Any handling event can stop propagation by calling stopPropagation() on the event.

3.Bubble phase—The framework executes the bubble phase from the source component to the application root until all components are traversed or stopPropagation() is called.

And the Direction in which propagation happens can be understood by below diagram

enter image description here

In your example your eventSource component is also present in the container component . Hence it is able to handle the event

<aura:component description="container" access="global">
    <aura:handler name="compEvent" event="c:compEvent" action="{!c.handleComponentEvent}"/>

    **<c:eventSource />**
</aura:component>

If the eventSource was not a part of container component then you would not be able to handle it .

Try commenting it from the container component and modify owner component to below

<aura:component description="owner" access="global">
 <aura:handler name="compEvent" event="c:compEvent" action="{!c.handleComponentEvent}"/>
  <c:container/ >
   <c:eventSource />
</aura:component>

Now you will see only owner component is able to handle it .

Check the below blog for a working playground to understand in depth .

  • "Try commenting it from the container component" I commented the code in the container component and made a minor change as per the salesforce example like below <aura:component description="owner" access="global"> <aura:handler name="compEvent" event="c:compEvent" action="{!c.handleComponentEvent}"/> <c:container> <c:eventSource /> </c:container> </aura:component> But now I am not able to see the eventSource.... Is there anything else do we need to do for contained component to display – Dheeraj_Vashist May 30 '18 at 10:54
0

I think difference how an event is handled depend on whether a component is owner or Container.

A container component has a facet attribute whose type is Aura.Component[], such as the default body attribute. The container component includes those components in its definition using an expression, such as {!v.body}.

Now lets say i have a owner component

<aura:component>
  <aura:handler <!--eventHnadler-->/>
  <c:container>
   <aura:set attribute = "body">
    <c:eventSource/>
   </aura:set>
  </c:container>
</aura:component>

In above case event fired by event source will not be handled by Continer Component.

Lets take a another case of owner component

<aura:component>
  <aura:handler <!--eventHnadler-->/>
  <c:container>
  </c:container>
</aura:component>

and container component is

<aura:component>
  <c:eventSource/>
</aura:componnet>

Now in above case event will propagate to both container and owner component.

In first case if we want to handle event in container component then add

includeFacets="true"

in handler.

<aura:handler name="bubblingEvent" event="c:compEvent" action="{!c.handleBubbling}"
    includeFacets="true" />

To allow a container component to handle the event, add includeFacets="true" to the tag of the container component. For example, adding includeFacets="true" to the handler in the container component, c:container, enables it to handle the component event bubbled from c:eventSource.

Source: https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/events_component_bubbling.htm

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.