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.
2 Answers
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();
}
})
-
1Hi 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. salesforce.stackexchange.com/questions/88767/… Commented Aug 25, 2015 at 1:23
-
I've elaborated my concerns about the navigation in a different question here salesforce.stackexchange.com/questions/97398/… - any feedback is welcome!– Uwe HeimCommented Oct 28, 2015 at 7:07
-
Like @DianaWidjajaMyerscough mentioned here salesforce.stackexchange.com/questions/97645/… there is more info in the current docs here developer.salesforce.com/docs/atlas.en-us.lightning.meta/… about dynamically creating components– Uwe HeimCommented Oct 29, 2015 at 16:33
-
3Hi @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?– VarunCCommented Nov 9, 2015 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 gist.github.com/frontendloader/34bfebf06c4fa3b61036 Commented Feb 1, 2016 at 21:06
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();
}
-
Will you give me a full working code example for this ? Commented Aug 25, 2015 at 1:43
-
@Troy, are you sure, that this functionality is really available? As discussed here salesforce.stackexchange.com/questions/97394/…, 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 HeimCommented Oct 29, 2015 at 8:41
-
Just check this out salesforce.stackexchange.com/a/133189/29317. It seems it'll be made available in Winter 17.– SE_UserCommented Aug 10, 2016 at 5:35