Jared the Nerd

Jared the Nerd

CTO, IT Advisor, Software Engineer, Public Speaker, Traveler, and 100% Nerd

Getting Started With Backbone.js

Backbone.js is one of those wonderful technologies that is flexible enough to let you solve problems in a variety of ways. It’s also one of those horrible technologies that don’t have any opinion about what the ‘correct’ way to solve a problem might be.

One big issue with backbone is the traditional ‘todo list’ problem of complex frameworks; namely, that all of the examples you can find are trivial applications that dont look at all like the apps you really build. There are some good resources for patterns and individual problems but when I was starting out I didn’t find a good overall process guide.

Through a lot of contemplation, trial, error, and bugging my friends (thanks @larrymyers) I managed to come up with some design patterns I’m happy with. Ive been using them successfully in Facio and hopefully they’ll be helpful to you. I won’t be talking about how to actually write the JavaScript as there are plenty of guides to that already.

Getting started

At the very top level of a backbone app (or backbone page in a traditional app) I start with either a router or parent view. If I need page state (history, linkable urls, etc) I go with the router approach. The router then initializes a parent view or views. If the page is simple enough I might just start with the view. Quite often there isn’t any real model data at this level to worry about since this view acts as a container of sorts. Then I start thinking about child views.

I figure out how many high level bits of the page I have. Often these correspond to containers on the page. Lets look at an example from Facio:

I have a nav area and a report area. These are candidates for creating children. The goals in the report are themselves children. Etc.

Pro tip: When I was first learning Backbone I had a tendency to create child views in the parent view’s render action. This causes views to be created way too frequently and will cause issues. Instead, I put a method called something like createChildViews on each view. This is generally either called by initialize or an Ajax callback.

Making (code) babies

createChildViews is tasked with looking at the model and creating whatever children need to exist. Those children may have their own createChildViews method that the parent will call. This will cascade down as many times as necessary for what I’m building.

I do a couple of things that I’ve found helpful when creating the children. First, I keep an array on each view that contains references to all of its children. I usually call this something like childViews or xyzChildViews with xyz being some description. Second, I create a property on the children called parent that points back to their parent. Third, I (sometimes) define methods in the view that give me back the entire chain of parents/grandparents/etc. This is helpful when I need to re-render something much higher up the hierarchy when a child is updated.

Each of these children will have a model or a collection inside of them. While I generally let me views know who their parents are,  my models are unaware anything else exists.

Painting the pretty pictures

So now that I’ve created the hierarchy of views (with their models or collections) I’d probably like them to render out. When I implement render I have it render the current view and then iterate over all its children and call their render methods. Those children render and call their children and so on. Because I’m not creating new views all the time I can avoid the common zombie view problem.

Cleanup

One more bit of boilerplate that I generally implement is a close method on each view. Close will go through and call close on all of the views children and then dispose of itself. This lets me make sure I dispose of anything I want to get garbage collected and fire any events that need to happen. Again, having references to children/parents makes this easier.

Testing

I never test the DOM. Instead I wire up DOM manipulations into little ‘private’ methods and assert they are called. Then I eyeball test the manipulation worked. This seems to buy me a lot at little cost.

My JavaScript is continuously changing but these strategies have worked for me lately and hopefully provide value to you.