JavaScript For The Impatient: BackboneJS (part 1)

Introduction to the Backbone JavaScript framework, third party libraries, and creating a ‘blog’ style web app.

GitHub repo


If you’ve ever used Hulu, Wordpress, AirBnB, or visited the USA Today website, you’ve used a web application. Specifically, a web application built on the BackboneJS framework.

Of course, there are many web apps out there, and there are many frameworks. Other popular JavaScript frameworks include EmberJS and AngularJS — they’re all great, I just prefer Backbone because I work with it on a regular basis.

Theoretically, and painfully, you could write a web app without ever touching a framework… This would make you an insane person. Frameworks utilize what is called the Model View Controller (MVC) architectural pattern. I could go on for a very long time about MVC but all you need to know is it works, it’s standard, and the wikipedia page on it is pretty short so go read about it there.

If you’ve been to the BackboneJS website and read any of the documentation, you would have seen things such as Models, Collections, and Views. I remember struggling to wrap my head around what exactly a collection was, how a model worked, and where is the controller in all of this? If frameworks are supposed to be MVC-centric, then why am I only hearing about model and view? Because the world is crazy and unfair, that’s why.

Just kidding.

As we get to these portions of the framework, I’ll explain them to the best of my ability.

Let’s talk about the project: Super Simple Backbone Blog. If you’re reading this on Medium, which I think you have to be unless you’re from the future (I’m onto you), then the end result of this little app should look pretty familiar. Like a personal blog. We’ll allow the ‘user’ to create blog posts, delete, and even update them.


SETTING UP

We need to set up the directory for our app to live in. I keep my projects in a directory called development, within the development directory I create the Super Simple Backbone Blog directory, I will call this folder the root.

Let’s begin by creating a directory, libs, in the root, to hold all of our vendor js libraries. Third party JavaScript libraries are extremely useful, and you’ll be using them a lot. But you should already know that if you read JavaScript For Cats. Backbone requires UnderscoreJS, so we’ll be putting that in libs, we’ll also be relying on jQuery, Handlebars, and JSON2. Place all of these libraries in the libs directory, including Backbone.

Add a css directory to root. Put Bootstrap in there, trust me it’ll make life easier if you learn bootstrap — might as well start now.

Next, let’s get an index.html file. Save this in the root.

Here’s what everything should look like:

If you opened this in Chrome right now, you’d see your boring html page. Good job. Open developer tools and check the console to make sure there are no errors.

Right click anywhere on the page, choose ‘Inspect Element’ then click ‘Console’. You should see nothing in the console.

CREATING THE APP

Create a directory, app, in root. Within app, create a file app.js. We’ll start with the contents in the snippet below:

Let’s talk about what’s going on in here. app.js is the actual app itself — this is where we’re using Backbone, so it’s fair to assume that this is all new to you.

The very first thing we do is create a View: DashboardView:

var DashboardView = Backbone.View.extend({ });

Backbone Views create a DOM element (a <div></div> to be precise, but you can make it whatever you want) by default, you can think of the View as occupying the space between this element. You can refer to the element that this view occupies as this.el or $el. Remember this because we’ll see this a lot.

We assign a Handlebars template to the view:

var DashboardView = Backbone.View.extend({
template: Handlebars.compile( $(“#dashboard-view-template”).html() ),

We will put our Handlebars template(s) inside index.html very soon. Essentially what we’ve done here is assigned a template to this view. Most, if not all, web applications are dynamic, we use templates to facilitate this. You have no idea what blog posts your users will create, so you wrap ‘them’ in a template that will update dynamically.

Every view in Backbone has an initialize: function() whether you define it or not. I did define it, because I want this view to render() as soon as it’s instantiated. Anything you put in initialize() will execute when the view is instantiated, in order.

var DashboardView = Backbone.View.extend({
template: Handlebars.compile( $(“#dashboard-view-template”).html() ),
  initialize: function () {
this.render();
},
  render: function () {
this.$el.html(this.template({greeting:”This will display a list of our blog posts”}));
}
});

Every view in Backbone has a render: function(). In this case, render() happens as soon as this view is instantiated, due to it being called in the initialize(). render() is passing in an object, with the property ‘greeting’, and ‘greeting’ has a value of “This will display a list of our blog posts” so we can access greeting inside the template and display whatever the value happens to be.

You can think of the way render() works by saying ‘The html inside this view’s dom element should be whatever the template is, and also let’s pass in this object with the property greeting.’

You should be able to ‘translate’ the line below to reflect that:

this.$el.html(this.template({greeting:”This will display a list of our blog posts”}));
}

That’s it for the DashboardView view. Continuing down, we have the AppRouter. Backbone’s Router is pretty easy to understand, and I encourage you to utilize it in the future (single page apps are great, but you usually want your user’s back button to work properly, and the url to reflect wherever they are, accurately — this is what a router does… actually, just go read about the router before you continue on)

A router is basically a set of routes, in our case we just have a default: dashboardRoute

var AppRouter = Backbone.Router.extend({
routes: {
‘’: ‘dashboardRoute’,

Notice the empty route to the left of the colon. This means this is where the app defaults to. To the right of the colon we have dashboardRoute, which is essentially just a function stored inside AppRouter:

var AppRouter = Backbone.Router.extend({
routes: {
‘’: ‘dashboardRoute’,
‘dashboard’: ‘dashboardRoute’,
‘create-blog’: ‘createBlogRoute’,
},
  dashboardRoute: function () {
var dashboardView = new DashboardView();
$(“#content-container”).html(dashboardView.el);
},

You can think of the router working like this: ‘The browser landed on the default page, lets run the dashboardRoute function. Alright, dashboardRoute wants me to instantiate a DashboardView and call it dashboardView, awesome — I’ve got this! Okay, so now I need to search index.html for an element with the id of content-container. I found it! Okay, lets put dashboardView’s html inside content-container. Alright my job is done!’

So, AppRouter did everything it needed to do when the user’s browser landed on the default page. And it did it all in like… nanoseconds or something. I don’t know but it’s really fast. Anyway — at this point the view DashboardView’s initialize() takes over, and we’ve gone over what that does.

Before we move on, let’s take a second to understand what an instance is, like when you instantiate a view, for example. DashboardView is a view that does whatever it does depending on what you tell it to do. But it is NOTHING until you instantiate it. It is just a shell, a stamp with no ink.

When you say:

var whatever = new DashboardView();

Now, ‘whatever’ is SOMETHING and it happens to be all the things that DashboardView is. Views are just JavaScript objects… If you don’t know what I’m talking about then GO READ JAVASCRIPT FOR CATS. UGH.

Alright, so we wrap up app.js with these two lines:

var appRouter = new AppRouter();
Backbone.history.start();

Guess what we did here? We instantiated the AppRouter, and called it appRouter. We did this because the very next line actually turns on the router.


UPDATE INDEX.HTML WITH THE TEMPLATES

Right now we have these mystery templates that we’re utilizing in app.js. Let’s put these in index.html and update some of the other html as well:

First, we get rid of our

<h1>Super Simple Backbone Blog</h1>

We replace it with a nav menu. I used Bootstrap for this because it’s fast and easy. You can learn more about Bootstrap over at getboostrap.com. Notice the links in the nav menu. We will be adding those to our router later.

Next, we add a new div, with the id “content-container”. Remember that the router looks for an element with the id of “content-container”? Now it will find it, and place the dashboardView in that element. Speaking of dashboardView, we need to make its template, that’s the next thing we do:

<script type="text/template" id="dashboard-view-template">
  <h1>Dashboard</h1>
  {{greeting}}
</script>

First, lets establish that this does not display on the page, it is wrapped in a script tag. Handlebars uses this — index.html itself doesn’t do anything with these templates. It will display on the page when a Backbone view calls the template to be placed in the view’s element. Are you still with me? Good.

The first thing in this template is just a standard heading tag, with Dashboard in it. The fun part is actually the {{greeting}}. Remember in the dashboardView when we did this:

this.$el.html(this.template({greeting:”This will display a list of our blog posts”}));
}

Handlebars is looking for that ‘greeting’ property, and it will replace {{greeting}} with whatever the value of ‘greeting’ is — which we passed into the template in dashboardView with “This will display a list of our blog posts”! This is a very simple implementation of dynamic templates, but you can see how this becomes useful for dynamic information. Later, we will get more use out this.

We created a second template for create-blog-template. Guess what… That means we’re about to add another view and update our router!

Finally, don’t forget to add the app.js file to bottom of your list of scripts, we need to run the app at some point.

<script src="libs/jquery-1.11.3.js"></script>
<script src="libs/underscore-1.8.3.js"></script>
<script src="libs/backbone-1.2.0.js"></script>
<script src="libs/handlebars-v3.0.3.js"></script>
<script src="libs/json2.js"></script>
<script src="app/app.js"></script>

UPDATE APP.JS WITH A NEW VIEW AND ROUTES

Let’s go back to app.js we need to add a new view CreateBlogView and add routes to allow the user to actually navigate:

We’ve been over what views do. There shouldn’t be much to CreateBlogView that you don’t already understand.

AppRouter has changed a bit. We added two more routes: dashboard and create-blog. However, we only added one more route function, createBlogRoute — this is because both ‘’ and ‘dashboard’ utilize the same dashboardRoute function — they’re both just instanciating dashboardView. createBlogRoute now instanciates createBlogView.

As you probably guessed, when you click the Dashboard and/or Create Blog links in the nav bar, the app will display the proper view.

Go ahead and open index.html in Chrome.

Show your support

Clapping shows how much you appreciated Corey Howell’s story.