6

My goal initially was to avoid pasting my common functions into every new components helper.js file (previously researched) and I found out that you can extend the components (some example codes) I tried making a very simple base/abstract component and extending it like so:

1.Abstract component:

<aura:component extensible="true">
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <!--<aura:handler event="aura:waiting" action="{!c.loaderStart}"/>-->
    <!--<aura:handler event="aura:doneWaiting" action="{!c.loaderStop}"/>-->
    <p>This is inside abstract</p>
</aura:component>

abstract controller

({
    doInit: function(component, event, helper) {
        console.log('doInit', component, event, helper);
    }
    /*
    loaderStart: function(component, event, helper) {
        console.log('loaderStart');
    },
    loaderStop: function(component, event, helper) {
        console.log('loaderStop');
    }
    */
})

abstract helper (just a bunch of simple stuff)

({
    closeQuickAction: function () {
        $A.get('e.force:closeQuickAction').fire();
    },
    refreshView: function () {
        $A.get('e.force:refreshView').fire();
    },
    navigateToRecord: function (recordId) {
        // 'slideDevName': ( 'chatter', 'related', 'detail' )
        $A.get('e.force:navigateToSObject').setParams({'recordId': recordId, 'slideDevName': 'related'}).fire();
    }
})

2.And the component that extends it:

<aura:component extends="c:CmpBase" implements="force:lightningQuickAction">
    <p>This is inside extender</p>
    <lightning:button type="button" label="Test"/>
</aura:component>

This components (2) content does not show. Why?

Edit: contents and the console.log of the abstract component do show!

Found the docs: https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/oo_cmp_attributes.htm

2 Answers 2

8

In the abstract component you need to place the body:

<p>This is inside abstract</p>
{!v.body}

which is where the extending component's content is placed.

(When I had this problem I didn't manage to find an explicit explanation, just that examples had the {!v.body} in the abstract component.)

0
2

I can't say that I have firsthand experience delving into the markup inheritance hierarchy, but I think the way it's explained under Inherited Body Attribute makes some sense of it - it being this requirement to include {! v.body } within the component markup of an abstract base component.

The inheritance behavior of body is different than other attributes. It can have different values at each level of component extension to enable different output from each component in the inheritance chain...

The default renderer for a component iterates through its body attribute, renders everything, and passes the rendered data to its super component. The super component can output the data passed to it by including {!v.body} in its markup. If there is no super component, you've hit the root component and the data is inserted into document.body.

There's also a concrete example provided.

This is sensical upon reflection (I think): if the inheritance hierarchy in the body weren't inverted in this fashion (super enclosing sub, rather than sub building on super), there wouldn't be a clear place for markup from the subcomponent to slot in.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .