Important Backbone tips

1. WHEN YOU REMOVE A VIEW… DON’T FORGET TO UNBIND YOUR EVENTS!

I’ve been caught on this way too many times. If you bind say a view to add a div on a collection add, navigate away and remove that view, then navigate back and create a new view it will start to add two divs at once because it’s now bound the events twice.

This makes me think it’s better to not remove views, but instead just hide them. To refresh the view with new content just re-render and delegateEvents.

2. ANY CHANGE TO THE DOM RE-RENDERS

This might not be a so common, but for me binding any model change to render seemed wasteful if I just wanted the one element to change for one attribute. Well it’s actually not wasteful, because whenever you manipulate the DOM in any way that adds/removes to it, the browser has to “reflow” or re-render everything anyways.

So re-rendering the entire container of something is just as good as re-rendering one piece of it.

The circumstances it’s not good to re-render everything is of course if you say want just that title to animate in some way after being changed (lets say it fades out and fades in a new element) then you wouldn’t want the whole form to do it’s normal re-render and group your render logic with this animation. It might be best to simple bind to that change.

swapTitle = (model) => @$(‘.title’).fadeOut ->

$(@).replaceWith(“<a>#{model.get(‘title’)}</a>”).fadeIn()

@model.bind ‘change:title’, swapTitle

3. FLASH MESSAGES ARE YOUR FRIEND IN ASYNC WORLD

When you work in an asynchronous single page app kind of environment, you can’t throw 404 or 500 pages automagically in someone’s face when something goes wrong on the server side.

This means having to account for a lot of error message handlers. To keep things DRY it would be best to have a re-usable module for this. A flash message (little fixed message that drops from the top of your page) can be used to un-intrusively handle most success and error responses.

But don’t forget the preloaders! There will generally be 3 states of UI to worry about at all times, success, error, and preload. Be sure to give some feedback while you make trips to the server if it might take more than a half second.

preloader()

model.fetch

success: -> alert(‘yay’); stopPreloader()

error: -> alert(‘boo’); stopPreloader()

This makes me wish Backbone would provide a preload: and possibly complete: option as well to keep things organized.

4. ROUTERS != CONTROLLERS

Routers are nothing more than something that listens for hash change events. These are almost nothing like controllers in traditional MVC frameworks like Rails. Fetching new models/collections and instantiating a new view with the models might actually not make sense in many cases as what to do in a Router. 

Routers should generally not deal with UI too much, but they can if it makes sense. Their job is simple: Deal with what happens on when a user changes hash route, nothing more.

CONCLUSION

Backbone is very powerful and flexible. But if you come from Rails-land you’ll notice this fertile Thick Client territory is much more configuration over convention. So keep an open mind about the responsibility of it’s components.

I’m happy to see Backbone 0.5.3 update Controllers to be called Routers, because Backbone is not like an MVC framework in the traditional web framework sense. It’s views act as controllers + UI logic, templates are like views, models/collections are more or less the same, and routers are just a little helper. But don’t just take my word for it, see what they have to say about it themselves.