3

I have a component that's really just a container. I'd like to be able to set an attribute on the container and have that attribute be able to passthrough anything I put inside the container without the user of the component having to pass it through.

ex: container

<aura:component>
  <aura:attribute name="att" type="string" default="true"/>
  <div>{!v.body}</div>
</aura:component>

ex: containee, a component that can go in the container

<aura:component>
  <aura:attribute name="attOffParent" type="string" default="true"/>
  <div>hi, {!attOffParent}</div>
</aura:component>

ex: implementation

<c:container att="foo">
  <c:containee/>
</c:container/>

obviously, I could pass in like <containee attOffParent="{!v.att}"/>

But is there a way to make it generally available to all the containees whenever they feel like using it, especially if they are a grandchild of the container and inside another component?

Open to ugly hacks, including going up the dom tree, using lightning events, etc.

8
  • I don't think that there is a standard way to do this, but I would be surprised if there wasn't a hack.
    – martin
    Commented Jul 30, 2015 at 1:33
  • 2
    Events !Use Events to notify .Events in lightning are meant for this . Commented Jul 30, 2015 at 3:04
  • 1
    @martin partly reducing complexity and verbosity in the markup, but especially for the grandchildren situation where everything upstream would have to have passthrough capability...what if it was someone else's component, but inside that you put yours that still needs to access Grandpa's attribute? Commented Jul 30, 2015 at 19:30
  • 2
    @MohithShrivastava is right. Parent-to-child notification is a key use case for an event. You fire the event from parent. If a child wants to do something with it, you're set. If not...ignored. Sorry I don't have time to write up an example or proper answer.
    – pchittum
    Commented Jul 30, 2015 at 22:22
  • 1
    I shouldn't comment on SFSE after 10 pm. I agree: better to set attribute values in children than events.
    – pchittum
    Commented Aug 3, 2015 at 22:59

3 Answers 3

1

Stick with passing the attribute value through to the child and grandchildren.

You could do something with an event firing in the parent to update attributes on the child and grandchild components, but it certainly wouldn't reduce complexity since you need to add the handlers in your components, it requires javascript in the controllers to fire and handle the events, and then of course there are the events themselves.

There are certainly use cases for that type of architecture, but keep in mind that when passing an attribute through to the controller it is automatically updated when changed in the parent, so the value that you are seeing is the current value in the parent, and not just a snapshot of what the value was when the component was rendered. You could create an application event that essentially recreates that functionality, but it is unnecessarily complex if this is all that you want to do.

Of course application events are certainly powerful tools, and there are instances where they your best/only option. It can be hard to make a general statement of when to use what, but if the following pattern works, anything else will likely just complicate matters:

<!-- The App -->
<aura:application >
    <aura:attribute name="att" type="Object" />
    <NameSpace:ChildComponent parentatt="{!v.att}" />
</aura:application>

<!-- ChildComponent -->
<aura:component>
    <aura:attribute name="parentatt" type="Object" />
    <NameSpace:GrandChildComponent grandparentatt="{!v.parentatt}" />
</aura:component>

<!-- GrandChildComponent -->
<aura:component>
    <aura:attribute name="grandparentatt" type="Object" />
</aura:component>
1

I eventually went with event model.

Short answer--the parent listens to the children, and selectively passes messages through based on its attributes. The kids only listen to events from the parent, not each other.

article: https://shane-force.herokuapp.com/2015/08/20/lightning-component-event-example/ code: https://github.com/mshanemc/lightningAccordion/tree/master/src/aura

0

An interface defines a set of attributes and can also include <aura:registerEvent> tags to denote which events it can fire. Define the attributes in an interface.

<!--np:myInterface-->
<aura:interface>
    <aura:attribute name="myBoolean" type="Boolean" default="true" />
    <!-- More attributes here -->
</aura:interface>

Implement the interface.

<!--np:myComponent-->
<aura:component implements="np:myInterface">
    <!--Redefine only if you need to override the value-->
    <aura:attribute name="myBoolean" type="Boolean" default="false" />

    myBoolean: {!v.myBoolean}
</aura:component>

You can see an example in the open-source framework. Most of our input components inherit the attributes defined in the ui:visible interface.

You must log in to answer this question.

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