Fancy working with a small team remotely? SupportBee is hiring developers!
Take a look at our jobs page

Chapter 8

Giving Each Screen a Bookmarkable URL

Now that we have some experience in building screens for our application, let's see how we can manage them better. Our pattern for showing screens has been something like this

This replaces whatever is currently in the body tag with the contents of the new screen. If we wanted some sections of the screen to persist, we could change the $('body') to $('#dyanamic_view') and only replace the contents in a specific div. However this simple approach as several drawbacks

  • The user cannot use the back button to navigate the application.
  • The screens cannot be bookmarked. You cannot email someone the link to a ticket by copying it from the browser's address bar.
  • Views need to know about each other. For example, the SB.Views.TicketSummary class initializes a new instance of the SB.Views.Ticket to open the ticket on click.

In this chapter, let's look at some techniques for managing multiple screens and solving some of these issues.

The Main View

Let's create a MainView class. You can also call this the App class or something more meaningful. Basically in our html page, we will initialize this class to start our app. Let's look at how this class would be used to get a better sense. This is the HTML returned by your server (even a single page app needs the first page sent back by the server and rendered as html in the browser).

This page will fetch all our assets and start the application by initializing the MainView. The code starts quite simple

In our HTML, we had defined an empty div with the id placeholder. We use this as the top-level element for the application. Everything else will now be populated inside this div. Finally we setup routes!

Setting up Routes using Backbone.Router

Backbone.Router provides us with the functionality needed to create linkable, bookmarkable, shareable URLs for important locations in the app. The documentation does a great job of explaining what the router provides but in a nutshell, it let's you map URLs to actions. You can add new routes anytime in your application and they are immediately available.

Our API follows a RESTful design pattern and it's nice to be able to have clean URLs for the app as well. For example, we want the URL /tickets/100 to show a ticket with the id 100. Let's look at some of the routes.

The function openTicket will be called whenever the URL changes to /:id. We didn't define the route as /tickets/:id because we want /tickets prefix for every URL and we can do that using Backbone.history. We had called a startApp method in the MainView. Let's define it now

Backbone.history handles the URL changed event and fires the right callback. We have used pushState to have URLs like /tickets/100 instead of /tickets#100. We need to ensure that whenever we load up the app, our server sends us the same page that initializes the SB.Views.MainView class. For example, in Ruby on Rails, this can be achieved with a routes like

URL Change First Pattern

Backbone provides a navigate function for the router. Whenever you reach a point in your application that you'd like to save as a URL, call navigate in order to update the URL. If you pass trigger:true in options, Backbone will also invoke the corresponding callback function (the one you set when defining the route). While this is optional, this is the pattern we use in SupportBee all the time.

If we reach a point in the application where we need to change the screen, we simply change the URL using navigate and make sure the callback is invoked. Following this pattern, let's change the openTicket method in SB.Views.TicketSummary (first defined here) to simply change the URL instead of initializing a Ticket View and then rendering it

SB.Utils.navigate is a simple wrapper that invokes the navigate function of the router with trigger:true. Changing the URL on click leads to much cleaner code. It also makes our single page app behave more or less like a regular app where URLS are changed on click and then things happen.

Tell Me What You Think!

What else would you like to see? What do you think is missing or not needed?

comments powered by
Disqus