To refer the most efficient way to navigate from one component to another, please refer the below post which has been updated in the Winter’17 release.

https://force-base.com/2016/11/06/lightning-components-navigation-re-defined-in-winter17-woooo-hooooo/

The technique mentioned in the above post is still in Beta mode, so you may continue to use the below approach until Salesforce generally announces it’s availability.

In my last post, I had briefed about Salesforce lightning events and its workflow. We will now walk through a  scenario wherein we implement a functionality of lightning events.

We build a lot of components when it comes to building a Salesforce lightning application. So, how do we bridge all of these components together ? Lightning events are the righteous way to achieve this.

Let’s assume a scenario wherein there are two components in which one component accepts two user inputs and adds the two values and there is another component which would simply display the added value. So, how will the component1 pass on the result to component2 ? Well, we define a lightning event for this scenario and allow component1 to fire the event, which can be caught by the event handlers of component2.

So, Let’s define a lightning event named as “NavigateToC2”. Since, the component1 will have a value to be passed on to component2, the event will also need to have an attribute associated with it.  So the event snippet should look something like this.

NavigateToC2.evt

<aura:event type="APPLICATION">

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

</aura:event>
 

We will now define the Component1 which would accept two input values from user and sum it. The code snippet for Component1 is pasted below

Component1.cmp


<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes">
   <aura:attribute name="Result" type="String"/>
   <aura:registerEvent name="navigate" type="c:NavigateToC2"/>

      <ui:inputText aura:id="n1" maxlength="5" size="5" label="Number1" required="true"/>
      <ui:inputText aura:id="n2" maxlength="5" size="5" label="Number2" required="true"/>
      <ui:button label="Sum" press="{!c.Calculate}"/>
</aura:component>

 

If you look at the above component, you will see that this component has registered the event “NavigateToC2” using the <aura:registerEvent> tag. This is a declaration that the component states to notify that it will fire the “NavigateToC2” at some point in time.

The controller for Component1.cmp is pasted below

Component1Controller.js


({
   Calculate : function(component, event, helper) {
      var a = component.find("n1").get("v.value");
      var b = component.find("n2").get("v.value");
      var res = parseInt(a) + parseInt(b);
      res = res + '';
      var evt = $A.get("e.c:NavigateToC2");
      evt.setParams({ "result": res});
      evt.fire();
   }
})

In the above controller of Component1, we are capturing the user inputs, converting it to integer data type, adding the two values and again converting it back to String data type. The final result is then passed to the “NavigateToC2” event and fired.

Now, we need to define the Component2, which will display the result. Below is the snippet of Component2.

Component2.cmp

 


<aura:component >
   <aura:attribute name="res" type="String" />
   The result is {!v.res}
</aura:component>

The above component is pretty straightforward.

So, now that both the components and events are defined, how do we bundle them all together?

We will need a parent component to bring all the components and event under one umbrella. So, let’s name the parent component as “MainComp”. This component will basically be rendering the different components at different point in time.

Below is the snippet of MainComp.cmp


<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes">
   <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
   <aura:handler event="c:NavigateToC2" action="{!c.NavigateComponent}"/>
   {!v.body}
</aura:component>

In the above component you will notice that I have incorporated the event handler for handling the event that will be fired by Component1. I didn’t incorporate this event handler in Component2 is because it is the MainComp.cmp that will render all the components. So putting the event handler in the Component which will render the other Components definitely makes sense.

The controller for the MainComp.cmp is pasted below

MainCompController.js


({
   doInit : function(component, event, helper) {
      $A.createComponent(
         "c:Component1",
         {

         },
         function(newCmp){
            if (component.isValid()) {
               component.set("v.body", newCmp);
            }
         }
      );
   },
   NavigateComponent : function(component,event,helper) {
      $A.createComponent(
         "c:Component2",
         {
           "res" : event.getParam("result")
         },
         function(newCmp){
            if (component.isValid()) {
                component.set("v.body", newCmp);
            }
         }
      );
   }
})

So, I will brief you about the functionality of MainComp.cmp. This component has two handlers viz; the “init” handler and “NavigateToC2” handler. The “init” handler is trigger when the component loads. This will invoke the “doInit” method and it will call the “createComponent” method, to which the Component1 is passed as an input parameter. Thus MainComp.cmp will render the Component1 during the initial loading.

So, what happens when the “NavigateToC2” event is fired by Component1. At this point, since the MainComp.cmp has declared the event handler for “NavigateToC2”, it will catch the event fired by Component1 along with the parameter passed to the event. The event handler in MainComp.cmp calls the “NavigateComponent” method, which ultimately invokes the createComponent method with the appropriated parameters passed to it from the event caught. Hence, the MainComp.cmp will now render the Component2.

If you have any queries, please feel free to comment.

Advertisements