I have a component that includes a child component. The child component has a button that fires showCustomModal on an overlayLibrary and the content is a dynamically created component.
Component hierarchy:
Parent
Child
Grandchild (Dynamically created)
The grandchild has a button that fires a component event that should be handled in the child component. The event fires, but is not handled. However, if I close the modal and re-open it and then click the button again the event is both fired and handled.
Parent component
<aura:component implements="flexipage:availableForAllPageTypes,forceCommunity:availableForAllPageTypes">
<c:TestChild />
</aura:component>
Child Component
<aura:component >
<aura:handler name="testEventName" event="c:TestEvent" action="{!c.handleTestEvent}" includeFacets="true"/>
<aura:attribute name="overlay" type="Aura.Component[]" />
<lightning:overlayLibrary aura:id="overlayLib"/>
<lightning:button label="Open Modal" onclick="{!c.createComponent}" />
</aura:component>
Child Controller
({
createComponent : function(component, event, helper) {
$A.createComponent("c:TestGrandChild",
{
testEventName: component.getReference('c.handleTestEvent'),
},
function(content, status, errorMessage) {
if (status === "SUCCESS") {
component.find('overlayLib').showCustomModal({
header: "Test Title",
body: content,
showCloseButton: true,
}).then(function (overlay) {
component.set('v.overlay', overlay);
})
}
});
},
handleTestEvent : function(component, event, helper) {
console.log('handled');
}
})
Grandchild component
<aura:component >
<aura:registerEvent name="testEventName" type="c:TestEvent" />
<lightning:button label="Fire event" onclick="{!c.fireEvent}" />
</aura:component>
Grandchild controller
({
fireEvent : function(component, event, helper) {
var componentEvent = component.getEvent('testEventName');
componentEvent.fire();
component.destroy();
},
})
Event
<aura:event type="COMPONENT" description="Test event" />
Best Answer
You might try instead of using component.getEvent('testEventName') in your grandchild controller, use
event.getSource()
.And then, when we handled the event in the parent component, we use
event.getSource
again.Our example isn't directly related to yours, but here is the reference of how we are using it and it has been working whether it be in a dynamic component where it gets created with create component, or when it is being explicitly used in markup.
Event
The event getting registered on the child
The child component event method
Handling the event on the parent
Then in the parent controller
Here is a link with more information on Handling Events with Client Side Controllers.