7

I have a table grid Lightning component where a child component is trying to modify single columns. The columns are passed in as shown below.

<aura:component>
    <aura:attribute name="table" type="Object" default="{ columns: [{...}, {...}],...}" />

    <aura:iteration items="{!v.table.columns}" var="column">
        <c:child singleColumn="{!column}" />
    </aura:iteration>
</aura:component>

But changes are never reflected in the parent. It seems not to see this changes of a fragment of its table attribute.

I thought Lightning might prevent child data modifications to enforce the use of events. But this is is not the case. When I pass in the full table it works.

<aura:component>
    <aura:attribute name="table" type="Object" default="{ columns: [{...}, {...}],...}" />

    <aura:iteration items="{!v.table.columns}" var="column">
        <c:child table="{!v.table}" singleColumn="{!column}" />
    </aura:iteration>
</aura:component>

But I don't want that. That would be bad modularization and encapsulation. I want sub components only have access to the data they work on.

Any chance to get that solved without using events?

2 Answers 2

1

I also experienced this strange behavior while changing data within aura:iteration.

The problem here is, that changes are affecting the data, but this change does not trigger the default change event. I guess it's a bug!

<aura:handler name="change" value="{!v.data}" action="{!c.applyChanges}" />

This won't work, for no valid reason. You could solve this, by throwing your own event, letting the parent know, that you changed the data. You don't need to pass the data itself, since the data is already updated, the parent just didn't get informed about it.

I just opened an issue at github to get this fixed asap.

1
  • If you find an authoritative SFSE reference for that and link it here, I will make this the "right" answer. Commented Oct 2, 2017 at 18:02
0

This would be where you'd want to define and use bubbling from the child component to the parent component. That means you'd want to use the <aura:registerEvent> tag in your child component's markup and then create an event listener in the parent component for the event that gets fired from the child.

In your case, I believe your code would look something like this:

First, let's define the event:

<aura:event type="COMPONENT">
    <aura:atrribute name="pk" type="string" />
    <aura:atrribute name="columnData" type="string[]" />
</aura:event> 

To retrieve the "pk" event data in your child component's handler, call event.getParam("pk") in the handler's client-side component.

In the child component, you'd add the following code:

<aura:registerEvent name=:"colclick" type="c:ColClick" />

To raise the event in JS from the child's handler, use:

({
    PnDomColClick : function(component,event,helper) {
       var compEvent = component.getEvent("colclick");
       //
       // set some data for the event 
       // (this is what I think you're probably missing most)
       // (it's also known as event shape)
       //
       compEvent.setParams({setParams({"pk" : 1, colData: ['A'] });
       compEvent.fire();
       }
})

Events bubble up to tags in the containment hierarchy. Define an event listener in a parent tag as below:

<aura:component>
    <aura:handler
    name="colclick"
    event="c:ColClick"
    action="{!c.handleBubbling}" />

</aura:component>

In your event handler you can access event parameters as follows:

handleBubbling: function(component,event,helper) {
    var params = event.getParams();
    alert("You selected: " + params.pk);
}

Calling event.stopPropagation() will prevent the event from cascading further up the hierarchy.

Calling event.getSource() returns the component that raised the event. (Note: not available for application events)

If you need to find source of an application event, use evt.setParams() to set the source component in the event data before firing it.

4
  • I know that I can do it with events. My question was if I can do it without. And if so why. Commented Sep 22, 2017 at 12:42
  • The only way you could do it without is by having attributes that all components share and setting the common attributes.
    – crmprogdev
    Commented Sep 22, 2017 at 13:33
  • 1
    @crmprogdev - Just fyi - I just went through this yesterday and the events failed to be handled when fired by dynamic components unless I remove the name attribute on the event handler. Think it is a bug but removing the name from the handlers was all that was needed to get it working. See: salesforce.stackexchange.com/questions/106392/… - Just in case someone runs into same issue
    – Eric
    Commented Sep 22, 2017 at 14:04
  • Yes, that does sound like a bug to me. The essence of what I wrote came straight from the Salesforce Univ DEV 601 Programming Lightning Components Class Materials from when I took it earlier this year.
    – crmprogdev
    Commented Sep 22, 2017 at 14:15

You must log in to answer this question.

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