[SalesForce] Navigation in a Lightning App

I am creating my first lightning application and am using the LDS UI framework. I have created a header component with a navigation bar, and embedded this component in my Lightning app.

<aura:application extends="force:slds">
  <c:Header />
  <c:Footer />
</aura:application>

What I would like to do is have the navbar (which is inside the header) link to other pages in the app, while using the same header and footer – only the body would change. Is there lightning functionality that accomplishes this? Or would I have to create another application to link to? If this is not normal architecture for a lightning app, please let me know as well. I would rather not use VisualForce too.

Best Answer

You are probably going to want to use "events" to do this.

The approach I would consider comprises the following:

1) A Navigation component with links/buttons that fire a lightning event (this is your header)

2) The Lightning Event (a separate component - this is new to your setup)

3) A "body" component (could be one, or many) that listens for the events and changes its content dynamically (even dynamically loading other components) (this is probably your footer)

So (1) will be a component with some HTML markup including a navigation item like:

<li><a href="#" onclick="{!c.activitySelected}">Activity</a></li>

And in the component controller a method that [calls a helper method that] does:

    performActivitySelected : function() {
        var navSelected= $A.get("e.c:navSelected");
        navSelected.setParams({ "name" : "activity" });
        navSelected.fire();
    },

The navSelected var in that then references (2) which is this Lightning event (note: the name of the event component has to line up with the $A.get from above)

<aura:event type="APPLICATION" description="Event from nav">
<aura:attribute name="name" type="String"/>
</aura:event>

and then finally, in the "main" body / footer component (3) you want some markup in the component to listen to these events and change the "body" area like:

<aura:component >
    <aura:handler event="c:navSelected" action="{!c.onMenuItemSelected}"/>
    <div aura:id="displayPort"></div>
</aura:component>

In the controller then (and use the helpers appropriately to delegate this lark) use:

onMenuItemSelected : function(component, name) {
        $A.createComponent(
            "c:" + name,
            [],
            function(newComponent, status, statusDetail) {
                var content = component.find("displayPort");
                content.set("v.body", newComponent);
            }
        );
}

so when the component hears the Event being fired, it loads a component - in this case - with the given name and shoves it into it's body - but you can do anything you like from that point.

Related Topic