28

What is the best way to create views in Lightning? And then, how would you navigate from one view to another? Conceptually I'm thinking that I'll have two components, ns:foo and ns:bar, and essentially I want to have a button in each component that will "navigate" to the other component or cause the other component to be rendered in place of the current component.

26

We've found in building S1 and other apps that a best practice for this is to first create (or use existing) events to represent the verbs (e.g ns:navigateTo) and then have a component that's job is to act as the container for ns:foo or ns:bar etc. You can make this event and handler generic if you want to and have the event contain the name of the component, attribute values, and even the destination facet name. In S1 we'be kept things fairly high level and modeled navigation as a small set of events like force:navigateToSObject (these will be access="global" - part of our public API - in Spring '15 BTW).

The actual view swapping can easily be done using facet (just an attribute of type Aura.Component[]) replacement - typically something along the lines of:

component.set("v.body", foo);

or using your own facet(s) other than body if you have multiple views you want to display simultaneously such as a header, content area, and footer.

There are a number of other patterns depending on your specific requirements - e.g. implementing something more like a tabset with tabs where you want to use component scoped events across a set of child views orchestrated by a common parent.

Here is an example of one way to use application scoped events (can be easily converted to component scoped) to switch from one view to another where the nav UI is embedded in the views being swapped. The example also demonstrates how to wire up a dynamically created component into an existing container and have full bidirectional data binding to the container's attributes.

ns:navDemo.app

<aura:application>
    <aura:attribute name="message" type="String" default="Hello"/>
    <aura:handler event="ns:navigateToView" action="{!c.navigateToView}"/>

    The message: <ui:inputText value="{!v.message}" updateOn="keyup"/>

    <div aura:id="content">
        <ns:fooView message="{!v.message}"/>
    </div> 

    <!-- Workaround for aura:dependency not being access="GLOBAL" to keep newCmpAsync() client side -->
    <aura:if isTrue="false"><ns:barView/></aura:if>
</aura:application>

ns:navDemoController.js

({
    navigateToView : function(component, event, helper) {
        var destination = "ns:" + event.getParam("view") + "View";

        $A.createComponent(this, { message: component.get("v.message" }, 
            function(view) {
               var content = component.find("content");
               content.set("v.body", view);
        });
    }
})

ns.navigateToView.evt

<aura:event type="APPLICATION">
    <aura:attribute name="view" type="String" required="true"/>
</aura:event>

ns:fooView.cmp

<aura:component implements="ns:view">
    <div>Using view 'foo': {!v.message}</div>
    <ui:button label="Navigate to bar" press="{!c.navToBar}"/>
</aura:component>

ns:fooViewController.js

({
    navToBar : function(component, event, helper) {
        $A.get("e.ns:navigateToView").setParams({view: "bar"}).fire();
    }
})

ns:barView.cmp

<aura:component implements="ns:view">
    <div>Using view 'bar': {!v.message}</div>
    <ui:button label="Navigate to foo" press="{!c.navToFoo}"/>
</aura:component>

ns:barViewController.js

({
    navToFoo : function(component, event, helper) {
        $A.get("e.ns:navigateToView").setParams({view: "foo"}).fire();
    }
})
0

Just following up, found this post last week and the Spring '15 release has made this a little easier it seems..

try

navToMyComp : function(component, event, helper) {
    var evt = $A.get("e.force:navigateToComponent");
        evt.setParams({
            componentDef: "namespace:MyComponent",
            componentAttributes: {
                myAttribute: component.get("v.someAttribute")
            }
        });
    evt.fire();    
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.