The handler name in your child component should match the registered name in the parent component. i.e., the handler in child component should be like this:
<aura:handler name="clrValues" event="c:ClearValues" action="{!c.clear}"/>
--UPDATE--
I think a better approach for parent-to-child communication is to use <aura:method>
as listed in lightning docs and here
To do this, you should define a method in child component like this:
<aura:method name="sampleMethod" action="{!c.clear}" access="PUBLIC">
You should then have an id when you refer it inside your parent component like this:
<c:ChildComponent textValue="test" aura:id="cComp"/>
Then in the clear method of the parent component, you should invoke the child method like this:
var childCmp = component.find("cComp")
childCmp.sampleMethod();
To attach the component(child) under a component(parent), you are doing following:
1.Create the component using $A.createComponent
2.Finding the parent component to attach the dynamic child using component.find(parentId) which returns the component instance(Aura.Component)
3.Then getting the body
of the above, then adding dynamic child to the body and setting the body
.
So, child component(dynamic) needs to be inside the body
of the parent component to be rendered in the view.
Also remember, you are attaching the dynamically created component to the body
of the <div aura:id="divDynamicChild"></div>
not to the actualy body
of the component <c:testFindDynamic_Parent>
.
So, you need to go deeper to get the actual instance of the dynamic child components that was created.
What you need to do is:
1.First, find the parent component instance using component.find("parentId").
2.Get the parent cmp body
because that's where the child cmp resides using parentCmp.get("v.body").
2.Since the child component resides in the 0th index of the parent component's body
attribute. You need to do this: parentBody[0].find("dynChildId").
var parentCmp = component.find("parentId");
var parentBody = parentCmp.get("v.body");
var childcmp = parentBody[0].find("dynChildId"); // returns the child component instance.
Now, your method buttonCallDynamicChildMethodPressed
method will look like this:
buttonCallDynamicChildMethodPressed : function(component, event, helper) {
console.log("DEBUG: (testFindDynamic_ParentController.buttonCallDynamicChildMethodPressed) Called.");
if (component.get("v.dynamicChildCreated") == true) {
console.log("DEBUG: (testFindDynamic_ParentController.buttonCallDynamicChildMethodPressed) ===== Try to find dynamic child inside the parent =====");
var divDynamicChild = component.find("divDynamicChild");
var divDynamicChildBody = divDynamicChild.get("v.body");
var dynamicChild = divDynamicChildBody[0].find("dynamicChild");
console.log("DEBUG: (testFindDynamic_ParentController.buttonCallDynamicChildMethodPressed) dynamicChild = " + dynamicChild);
console.log("DEBUG: (testFindDynamic_ParentController.buttonCallDynamicChildMethodPressed) ===== Try to find dynamic child inside dynamic div =====");
console.log("DEBUG: (testFindDynamic_ParentController.buttonCallDynamicChildMethodPressed) divDynamicChild = " + divDynamicChild);
console.log("DEBUG: (testFindDynamic_ParentController.buttonCallDynamicChildMethodPressed) dynamicChild = " + dynamicChild);
}
},
Here's an sample app:
child.cmp
<aura:component access="global">
<aura:attribute name="message" type="String"/>
<div>{!v.message}</div>
</aura:component>
parent.app
<aura:application >
<aura:dependency resource="markup://c:child" />
<ui:button label="greetings"
class="slds-button slds-button--neutral"
labelClass="label"
press="{!c.greetings}"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<p>Dynamically created button</p>
<div aura:id="test"></div>
</aura:application>
parentcontroller.js
({
doInit : function(cmp) {
$A.createComponent(
"c:child",
{
"aura:id":"test1",
"message":"Good morning"
},
function(newChild){
if (cmp.isValid()) {
var parent = cmp.find("test");
var body = parent.get("v.body");
body.push(newChild);
parent.set("v.body", body);
}
}
);
$A.createComponent(
"c:child",
{
"aura:id":"test2",
"message":"Have a nice day"
},
function(newChild){
if (cmp.isValid()) {
var parent = cmp.find("test");
var body = parent.get("v.body");
body.push(newChild);
parent.set("v.body", body);
}
}
);
},
greetings : function(cmp) {
var d = cmp.find("test").get("v.body");
console.log("child 1",d[0].find("test1").get("v.message"));
console.log("child 2",d[1].find("test2").get("v.message"));
}
})
Best Answer
I would suggest to dynamically create your child component when the user clicks the 'Edit' button. And when he clicks 'Save' you can use a Lightning Event to trigger the parent component to fetch the data again from the server and use a
component.destroy()
to remove your child component from the DOM. That should work all the time.If needed I can work out a small demo component so you can understand this further. Let me know.