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.

sfdcfox
  • 489,769
  • 21
  • 458
  • 806
Marty C.
  • 4,439
  • 6
  • 31
  • 61

2 Answers2

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();
    }
})
Doug Chasman
  • 10,054
  • 23
  • 36
  • 1
    Hi Doug, I am very Confuse of this example. Can you tell give me another example without that v.message . A simple redirection from 1 component to another component. When i click the button on the first component , it will cause the second component to rendered the place of the other first component. http://salesforce.stackexchange.com/questions/88767/lightning-app-redirect-from-1-component-to-another-component – Danryl Tigol Carpio Aug 25 '15 at 01:23
  • I've elaborated my concerns about the navigation in a different question here http://salesforce.stackexchange.com/questions/97398/what-navigation-pattern-for-lightning-community-created-be-the-new-community-bui - any feedback is welcome! – Uwe Heim Oct 28 '15 at 07:07
  • Like @DianaWidjajaMyerscough mentioned here http://salesforce.stackexchange.com/questions/97645/is-a-componentservice-newcomponentasync-available-in-lightning/97678#97678 there is more info in the current docs here https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/js_cb_dynamic_cmp_async.htm about dynamically creating components – Uwe Heim Oct 29 '15 at 16:33
  • 3
    Hi @Doug-Chasman - I am trying to work on the provided code but I am not able to understand what does this implements="ns:view" in both foo/bar components refer to? – VarunC Nov 09 '15 at 18:10
  • There were a couple things that didn't work right out of the box, but the concepts are all there. I wrote up a GIST that should help shed light on your question @VarunC https://gist.github.com/frontendloader/34bfebf06c4fa3b61036 – frontendloader Feb 01 '16 at 21:06
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();    
}
Troy
  • 109
  • 1
  • 4
  • Will you give me a full working code example for this ? – Danryl Tigol Carpio Aug 25 '15 at 01:43
  • @Troy, are you sure, that this functionality is really available? As discussed here http://salesforce.stackexchange.com/questions/97394/is-a-gete-forcenavigatetocomponent-available-and-documented-in-winter16/97614#97614, there could be doubts about it's availability and I wasn't able to use it in my tests. Please give us a short feedback if you are sure, that this is defacto working. – Uwe Heim Oct 29 '15 at 08:41
  • Just check this out http://salesforce.stackexchange.com/a/133189/29317. It seems it'll be made available in Winter 17. – SE_User Aug 10 '16 at 05:35