[SalesForce] Reference Elements in Child Lightning Component from Parent

I want to be able to reference an element in a Lightning component that's nested in a parent component.

Child component (named "MyChildComponent")

<aura:component>
    <lightning:input aura:id="childComponentElement"
                     type="text"
                     label="My Child Component Input" />
</aura:component>   

Parent component

<aura:component>
    <c:MyChildComponent aura:id="childComponent" />
</aura:component>   

I'm trying to reference the child from the parent controller.js so I can hide the input at certain times:

Parent Controller.js

var myChildComponentElement = component.find("childComponentElement ");
$A.util.addClass(myChildComponentElement , "slds-hide");

But that doesn't seem to work. Any thoughts?

Best Answer

Although below method is possible as of today in AURA, this is anti pattern according to LWC DOM access containment - https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.security_locker_dom

Since both parent and child components are in same namespace, you can modify the elements inside child component from parent like below :

    let childComponent = component.find("childComponent");
    let childComponentElement = childComponent.find("childComponentElement");
    $A.util.addClass(childComponentElement , "slds-hide");

However you cannot access elements inside childComponentElement since it is of lightning namespace.


A better approach (future proof) would be to use public methods:

Parent.JS:

let childComponent = component.find("childComponent");
childComponent.toggleInput("childComponentElement");

Child.cmp:

<aura:component >

    <aura:attribute name="element" type="String" />

    <aura:method name="toggleInput" action="{!c.toggleInput}" >
        <aura:attribute name="element" type="String" />
    </aura:method>

    <lightning:input aura:id="childComponentElement"
                     type="text"
                     label="My Child Component Input" />

</aura:component>

Child.JS:

toggleInput : function(component, event, helper) {
    let element = event.getParam("arguments").element;
    $A.util.toggleClass(component.find(element), "slds-hide");
}