-
Notifications
You must be signed in to change notification settings - Fork 0
Frontend Routing
Routing is very important for Single Page Applications (SPA for short). It allows the user and the browser to keep track of the state of the application, and to be able to return to that state easily.
The browser location refers to the current url that the browser is pointing to.
vs
In normal websites, this value is automatically updated when you click on a link because the browser is navigating to a new url and doing a GET request at that url. However in SPAs, the browser isn't navigating to a new url, but is usually doing an XHR behind the scenes to get new data. This means that the browser doesn't automatically update the location when a link is clicked.
Updating the location allows for a design architecture called REST, or Representational State Transfer. Basically, since a server has no knowledge of the "state" a user is in (for example, what page the user is viewing), REST uses the browser location to decode that state. Let's see an example of this:
Suppose I visit my new SPA, http://bestsiteever.com. On that site, I have an
"About" page. If I click a link to show the "About" page, but don't update the
location of the browser, the browser will still point to
http://bestsiteever.com. Now suppose I want to bookmark this "About" page.
Since the browser location hasn't been updated, I am effectively bookmarking the
"Home" page. However, if I update the location manually to be
http://bestsiteever.com/about I can bookmark the "About" page directly.
We can update the location of the browser by using Backbone's built-in history
functionality and Marionette's AppRouter.
The AppRouter allows us to define new routes in our app, and what should happen when those routes are visited. Here's an example:
import AboutModule from 'app/AboutModule';
const region = new Marionette.Region({ el: 'body' });
const MyRouter = Marionette.AppRouter.extend({
// Define the new routes the app should have. In this case, we are adding an
// 'about' route so that when Backbone navigates to
// http://bestsiteever.com/about, it will fire the associated method
routes: {
about: 'showAboutPage'
},
showAboutPage() {
const aboutModule = new AboutModule();
aboutModule.show(region);
},
});
By `new`ing the router, it will automatically register it's routes with the Backbone router so that they are handled correctly.
new MyRouter();And that is all you need to create a new route for your app. When the user clicks on a link to view the "About" page, the browser location will be updated and a new view will be rendered.
Navigation refers to how the user gets to a page versus what happens when a
user goes to a page. Going back to a normal website, you simply create an
hyperlink with an href attribute:
<a href="about">About</a>This won't work by itself for SPAs because the default behavior of the browser will be to navigate to the new URL, do a GET and render the response. We want Backbone to handle the routing, not the browser.
There are two ways to handle this. One is to use Backbone.history.navigate
directly which will cause Backbone to route to the desired location. Another is
to override the functionality of clicking on an hyperlink, parse out the
location the user is trying to go and then use Backbone.history.navigate to go
there. We use both techniques in Agent.
const MyView = Marionette.ItemView.extend({
template: _.template('<div>Hello World</div>'),
// The events hash contains events to listen for and the action to initiate
// when that event happens
events: {
// Listen for the 'click' event on any element that has the class
// 'about-link'. When that event happens, call the 'goToAbout' method
'click .about-link': 'goToAbout'
},
// Define goToAbout that will be called when '.about-link' is clicked.
// The 'e' parameter is the event object passed in from the event
goToAbout: function(e) {
// First, we want to block the browser from doing its default behavior
e.preventDefault();
// Now manually navigate to where we should go. The first parameter is the
// location to go to, the second determines whether Backbone should also
// trigger the associated action with that route. It should almost always
// be 'true'
Backbone.history.navigate('about', true);
}
});The other way is to add an attribute to the hyperlink that serves to flag this link as a SPA link:
<a data-link="spa" href="about">About</a>Agent will automatically catch clicks on links with this data attribute and use Backbone to route instead of the browser.
Next: Views & Templates
We hope you enjoyed this helpful Agent training document. If you see an error or omission please feel free to fork this repo to correct the change, and submit a pull request. Any questions? Contact Support.