salt-encrusted keystrokes

ripples of code from a surfer in the middle of the         pacific ocean

jsgems.org wtf

Tonight I got frustrated and purchased the jsgems.org domain with the hopes of bringing rubygems/bundler-esque dependency management to the javascript community.  The ruby/rails community’s got its act together, and it’s about time the javascript community does too.

I don’t really have a clue what I’m doing… but that’s the beauty of open source now isn’t it! https://github.com/rubygems/rubygems.org/ and https://github.com/carlhuda/bundler should serve as great foundations.

More to come once progress has been made…

eventful backbone models with before, after and failed events

Since the guys over at backbone don’t think this functionality belongs in the core you’ll have to add it yourself. Luckily that’s pretty damn easy to do. Just use the code below and replace your extend Backbone.Model with extend Backbone.EventfulModel and you’re up and running.

backbone identity maps in coffeescript

With the acceptance of #1970, it’ll soon be a cake walk to add an identity mapped model to Backbone. Crazy how one line of code can make what was previously a major headache an enjoyable walk in the park.

Once the new version has been released and the related gems have been updated, I’ll show you how to implement identity maps in backbone/coffeescript.

Organizing your Backbone.js code

Backbone is great but it still needs some polishing.  These organizational tips should help get you up and running.

Directory Structure

When I first started out with Backbone, the recommended directory structure rubbed me the wrong way:

  • Why are collections glorified and given their own directory? They’re still “models”, no? 
  • Why are templates glorified and given their own directory?  Are they model-code? No.  Are they controller/router code? No! A template’s sole existence is confined to views.

So yeah, I wasn’t happy with the models/collections/templates/views directory structure.  Instead I went with the following (for the rails asset pipeliners these are all relative to the /app/assets/javascripts/app directory):

/models
/views
     /templates
/routers

To use that structure in the asset pipeline, you’ll need to set up your requires like so:

#= require_tree ./models
#= require_tree ./views/templates
#= require_tree ./views
#= require_tree ./routers

Collections are models (just not Models)

Right now you might be thinking, “wait… where the hell did the collections go?” Well for now I’m lumping the model and collection definitions into a single file named after the model. For example, if I have a Surfboard model, /models/surfboard.js.coffee would look something like this:

Until either class expands significantly, this’ll do me just fine.

Notice that I also create a global instance of the collection, named after the model (capitalized and pluralized). This collection instance will be bootstrapped by the rails view and will always be available for event bindings by any class.

Bootstrap your collections

If you know you’re going to need the data, bootstrap it. It’ll speed up the initial user interactions and saves you a round trip to the server.

Only namespace when you need to

I hate writing javascript code that looks like bad Java code. You know, things like new MyApp.Backbone.Models.MyModel( yadayada ). It makes programming unenjoyable and leaves a bad taste in my mouth. If the class is a class you’ll be using a lot and is global in nature, just define it in the global context (within the rails 3.1 asset pipeline this implies prepending window. to your class names).

THIS ONLY APPLIES TO APPLICATION CLASSES! Libraries should always be namespaced.

Namespacing classes this way is an art and not a science, just try to be consistent. Here’s an example of my naming scheme: let’s say I’m building a site that sells bikinis. I’ll be dealing with bikinis all over the place and Backbone.Models.Bikini just isn’t sexy enough for me. Instead, my model class will be Bikini, the collection will be BikiniCollection, and the primary view will be — drum roll please — BikiniView.  All in the global namespace — easy to write, easy to read, easy to comprehend.  We’re done here.

That’s it for now.  More to come later.  Hopefully this saves you from some of the initial organizational-headaches I suffered while readying Kumu for Backbone.

Responsive UIs built on Backbone.js and Rails 3.1

For my work on Kumu I needed to build a richly-interactive graph interface.  The same data is shown in multiple places, and changes to it need to be reflected immediately across all views.

Originally I wrote everything from scratch but as the scope of the project grew, the code became hard to manage.  Thankfully Backbone and the Ruby on Rails team came to the rescue!  With the release of Rails 3.1 and the new asset pipeline Backbone was easy to integrate.

In the process I’ve come up with a few best practices that make Backbone easier to work with.  I’ll outline some of those best practices in future posts, but today I want to focus on one aspect directly related to responsive UIs: the Backbone.Collection class.

When I use the phrase “responsive UIs” I mean UIs that immediately reflect any and all changes without first relying on a request/response cycle.  Ideally, the fact that data is being stored and retrieved from the server would be totally hidden from the user. (There are some times when you want/need data to be lazily-loaded and that’s fine — the key is just to be aware of the difference and the impact each has on the user experience).

As I began working with Backbone and the Backbone.Collection class specifically, I was surprised to see that the collection.create() method first does the request/response cycle and then adds the model to the collection.  For Kumu, when a user adds an element, we want that element to immediately appear in the graph (valid or not — though client-side validations will catch most common errors) and then send the request to the server in the background, using the response to handle any server-side errors.

I noticed this pattern in a number of places and decided to wrap the behavior into a class called Backbone.ResponsiveCollection (and yes I’m using Coffeescript for most of my javascript coding now, but no I’m not satisfied with it — it’s just better than writing plain old javascript):

Using extensions like the class above and the beauty that is Backbone, you’ve got a great toolset for building richly-interactive and responsive UIs.