2

I have the following instance of the component list, in its body I pass multiple instances of item components:

<c:list id="testId" action="c.getItems">
    <aura:set attribute="items">
        <c:item data="Id" title="Id Clmnn" type="link"/>
        <c:item data="Name" title="Account Name"/>
        <c:dataColumn data="LastModifiedDate" title="Account Date" type="date"/>
    </aura:set>
</c:list>

Behind this instance there is component and related controller, where I get all items and try to call js controller of inner component to get some json data:

onInit: function(component, event, helper) {
    var items = component.get('v.items') 
    for (var i = 0; i < items.length; i++) {
        var item = items[i];
        //call method on item component controller: ??? item.get('c.onInit').$meth$ ???
    } 
}

How to call js controller function on inner component from js controller function on outer component? What is the valid way to call js controller function from instance of that component ? From js inspection tool I see item.get('c.onInit').$meth$ as a way to go, but this way is not documented so is not guaranteed to be safe.

From spec https://cs11.lightning.force.com/auradocs/reference.app#reference?topic=api:Action, I see there is method run but it is deprecated

2
  • u can use events to communitcate between the components / js controllers Mar 6, 2015 at 4:29
  • my case is not about communication. it is about decouple component behavior (rendering). Child/inner specific rendering is responsibility of child/inner component. And parent/outer can call child/inner.render interface method inside Parent.render method.
    – Natallia
    Mar 6, 2015 at 5:37

1 Answer 1

2

You could use Application Events to facilitate communications between controllers without creating a strong coupling between them. The documentation has a whole section on them which should get you off to a good start:

Create Custom Application Event

You can create custom application events using the <aura:event> tag in a .evt resource. Events can contain attributes that can be set before the event is fired and read when the event is handled.

Use type="APPLICATION" in the <aura:event> tag for an application event. For example, this is an application event with one message attribute.

<aura:event type="APPLICATION">
     <!-- add aura:attribute tags to define event shape.
       One sample attribute here -->
     <aura:attribute name="message" type="String"/>
</aura:event>

The component that handles an event can retrieve the event data. To retrieve the attribute in this event, call event.getParam("message") in the handler’s client-side controller.

Register Application Event

A component registers that it may fire an application event by using <aura:registerEvent> in its markup. Note that the name attribute is required but not used for application events. The name attribute is only relevant for component events. This example uses name="appEvent" but the value is not used anywhere.

<aura:registerEvent name="appEvent" type="auradocs:appEvent"/>

Fire Application Event

Use $A.get("e.myNamespace:myAppEvent") in JavaScript to get an instance of the myAppEvent event in the myNamespace namespace. Use fire() to fire the event.

var appEvent = $A.get("e.auradocs:appEvent"); // set some data for the event (also known as event shape)
//appEvent.setParams({ ... });
appEvent.fire();

Handle Application Event

Use <aura:handler> in the markup of the handler component. The action attribute of <aura:handler> sets the client-side controller action to handle the event. For example:

<aura:handler event="auradocs:appEvent"
 action="{!c.handleApplicationEvent}"/>

When the event is fired, the handleApplicationEvent client-side controller action is called.

3
  • But my case is about decoupling rendering of inner and outer components, it is not event-driven scenario. Inner component knows about itself and can feed json data to outer component so the outer component can finalize its initialization. It is like the following: table has its own render method, child columns have its own render method. So I am trying to call childColumn.render to build the whole table structure. Don't need to run event-driven approach
    – Natallia
    Mar 6, 2015 at 5:30
  • Anything you need to send between the controllers can be done by events. This stuff is a lot more asynchonous that Apex deveopment. What exactly are you trying do achieve by sending data from the child to the parent?
    – Matt Lacey
    Mar 6, 2015 at 7:29
  • More specific example, List is table of 100 rows. item is column (5+ columns) Havings 500+ events is not good idea). Column's render function (in js controller ) returns json config based on attributes (data, title, etc) like {mData: 'Id', title: 'Id'}. List(table) render function (function in js controller calls ) loops columns attributes, build aoColumnsDef array and pass column config to jquery datatables initialization: $('elId').dataTables({aoColumnsDef: []});
    – Natallia
    Mar 6, 2015 at 9:06

You must log in to answer this question.

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