This post originated from an RSS feed registered with Ruby Buzz
by Chris Nelson.
Original Post: 2 easy things you can screw up in backbone
Feed Title: MysteryCoder
Feed URL: http://mysterycoder.blogspot.com/feeds/posts/default
Feed Description: Ramblings of secret Ruby coder in Cincinnati, OH
First off let's be clear. Backbone is awesome. It's totally changed the way I develop web applications for the better. Before backbone, working on javascript code for a rich client web app was a miserable experience. With backbone (and coffeescript) I'm now enjoyably writing code I can be proud of. But because we are now developing our apps in a new way, we've found new ways to mess things up ;) Here are a couple ways we found that could save you some hours of frustration if you avoid doing them.
Don't have multiple views using the same element
This one I did early on in my backbone days the first time I had one view that created another view. Imagine some code like the following:
Seems ok at first. When we click a button in FooView it creates a BarView giving it an element and telling it to render. The problem happens the second time the button gets clicked. At that point you have 2 instances of BarView which each use the same element. And if those BarViews are listening to events on (or within) said element, mayhem ensues. I've found it to work out better to write the code like so:
In this version the BarView is created during the render method, right after his element has been created presumably. Then the BarView instance is displayed when needed. I've found this to be a good rule of thumb: backbone view objects should have the same life cycle as their elements. They should be created when their elements are created and destroyed when they are removed.
Beware model defaults that initialize complex attributes
The second gotcha I've run into cost us a good few hours today actually. Backbone models have a nice feature for allowing default attributes. It's a handy feature, but by using it to initialize array or object properties we found it caused a subtle (to us) but pretty terrible bug. In our model we had code like so:
The problem here is what happens when you create a second Foo. Turns out backbone does a shallow clone of defaults, which means the same array object in memory is used for both. This spec describes the problem nicely:
Turns out there is a pretty easy fix for this too. Defaults don't have to be an object literal, they can also be a function and backbone will be smart enough to invoke it to build the model's attributes. In coffeescript, this fix is exactly 2 characters:
Hopefully these two tips will save you some frustration as you dig deeper into backbone. In a future post I'll share some of the code we've refactored out of our app that we feel like is generally useful for other backbone + coffeescript + rails apps.