Don’t Limit Your Backbone Apps To Backbone Constructs

I’ve noticed a pattern in Backbone sample apps, requests for help via StackOverflow and the Google group, etc, where people realize that they have a need for an object that coordinates various parts of the application. This is a great realization and something that you should do when you see the need. However, most of the examples and sample that I see end up using a Backbone construct to handle this coordination – even when there is no direct benefit.

I don’t blame the people that are posting these example and questions, though. I think the problem stems from the learning curve of something new, and wanting to build something the way you see it being done in examples. I’ve seen this problem a number of times in my career and I’ve do the same thing when I’m learning something.

Here are a few of the examples that I think are causing problems for people, when learning.

The To-Do List’s AppView

A lot of people look at the simple to-do list example from Backbone, including me. It’s a great place to start if you want to see one way of building a small application with backbone. Unfortunately, when people see the AppView portion of the code, they often think that this is “the backbone way”. I thought this when I saw it at first, but I didn’t understand why it was this way. It didn’t seem right to me, but I didn’t question it as I was just learning backbone for the first time.

I built my first app with an AppView and it looked something like this (though honestly, it looked much much worse than this):

AppView = Backbone.View.extend({

  initialize: function(){
   this.router = new AppRouter();
   this.collection = new MyCollection();
   this.someView = new SomeView();
   this.someView.render();
   Backbone.history.start(); 
  }

});

Sure, this was worked for my simple app – it got things started up and running when i called `new AppView()`. It’s even better than putting all of that code right out in the middle of nowhere-land, where it would all become part of the global object. I was proud of myself for not pollution the global object! … but code like this shouldn’t exist in a view.

The Truth About AppView

If you look at the AppView in the to-do list example, and really read through the sample code, you’ll notice that it really is a backbone view. It registers events through the `events: { … }` attribute. It uses `this.$(…)` to do element selection within the view. It renders things into the DOM for display, too.

The AppView in the to-do list is a legitimate backbone view. It also happens to be the place that the to-do list starts up. This isn’t because AppView is the “the backbone way” of starting up an app, though. It’s only because there is no need for anything more complex in this example application. Nothing more.

Not Just Views

Its not just backbone views that get abused like this, though. I’ve seen examples where people build “controller” objects (which is a good idea, again) using a backbone model as the base class. In one particular example, the developer was using the events built into the model. The idea was good, but it was unnecessary to use a backbone model as a base class when backbone provides an event system that can be used anywhere.

You Have All Of Javascript Available. Use It.

This is the crux of what I’m trying to get at, really. When you recognize the need for an object that does not appear to fit within the constructs that backbone provides, don’t force it into one.

The next time you see a need for an application object that you can kick-start the app with, build your own object to do exactly that:

function MyApp(){
  var router = new MyRouter();
  var myCollection = new MyCollection();
  var someView = new SomeView({collection: myCollection});
  
  this.start = function(initialModels){
    myCollection.reset(initialModels);
    someView.render();
    Backbone.history.start();
  }
}

var someModels = [...];

new MyApp().start(someModels);

And when you want to take advantage of backbone’s events, just use backbone’s events:

// simple, object literal event thingy
var myThingy = _.extend({}, Backbone.Events);

// or a full object
function MyThingy(){
  _.extend(MyThingy.prototype, Backbone.Events);

  // other stuff here
}
var myThingy = new myThingy();

// use events!
myThingy.trigger("some:event");

You’ll find your code is much more understandable, less prone to strange behavioral bugs, and generally much cleaner and easier to work with if you remember that you can use all of javascript and not just the constructs that backbone gives you.


Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Derick Bailey

Derick Bailey is an entrepreneur, problem solver (and creator? :P ), software developer, screecaster, writer, blogger, speaker and technology leader in central Texas (north of Austin). He runs SignalLeaf.com - the amazingly awesome podcast audio hosting service that everyone should be using, and WatchMeCode.net where he throws down the JavaScript gauntlets to get you up to speed. He has been a professional software developer since the late 90's, and has been writing code since the late 80's. Find me on twitter: @derickbailey, @mutedsolutions, @backbonejsclass Find me on the web: SignalLeaf, WatchMeCode, Kendo UI blog, MarionetteJS, My Github profile, On Google+.
This entry was posted in AntiPatterns, AppController, Backbone, Javascript. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://www.stephenbelanger.com Stephen Belanger

    Great advice! I’ve seen far too many backbone apps that abuse the Backbone constructs and equally as many that don’t use the event system as much as they should.

  • Randy

    So, I am going to play the Backbone.js newb card here (because that’s the only card in my hand).  

    What exactly *is* the right way to develop Backbone.js apps if the todo example is not the correct way?  There is something very pragmatic and practical with having an example app to work from.  For example, Rails scaffolding was how a lot of people learned Rails.  

    • http://mutedsolutions.com Derick Bailey

      there’s not necessarily anything wrong with the to-do list. i’m even defending the AppView from that app in my post… the problem is not the to-do list or how it’s built. the problem is assuming the to-do list represents the one-true-way to build backbone apps. 

      the to-do list is a very small, very simple app. it doesn’t need much in terms of infrastructure. it doesn’t need an event-driven architecture. it doesn’t need to always keep every last detail cleanly separated from other bits. 

      if you’re learning and/or building a very small, very simple app, then follow along with the to-do app’s example. the most important thing to learn from this example is not _how_ or _what_ it does, but _why_ it does things the way it does. 

      my post is trying to shed a little light on why, and help people understand the scope of this sample app, so that they can see where their own apps and larger apps should diverge from that sample.

      hope that helps clear things up

    • http://mutedsolutions.com Derick Bailey

      ok, i missed your original question in that reply… there are not necessarily any “right” or “wrong” ways to build a backbone app. backbone is a very flexible system and you can build apps in many different ways. each of the different approaches that are possible have pros and cons, and fit better or worse to a given scenario. 

      i tried to show how the appview fit the scenario of the simple to-do list, and also show that it is not the only way to build an app launcher object.

    • Marco Rogers

      There’s no *right* way to develop anything (though there are usually several wrong ways). The right way is the way you understand and that works best for your requirements. What I got from this post is that you should try to recognize false constraints, like using backbone constructs everywhere. And you should try to break out of that mindset if it leads you to a simpler or more flexible architecture.

  • http://RileyStrong.com Riley Strong

    Thanks for the post – this kind of validates what I’ve been doing with Backbone.  Because our application has many independent pages, I extended “Backbone.View” to make “PageView” which loads resources,  rigs up events, calls in regular views, and renders the foundation of the page.  It does all the things of a regular View… and then some.

    Do you think that makes sense?

  • http://needforair.com/ Louis Chatriot

    I totally agree with this, but I think you can take it a step further. It is true for any framework, sometimes what you want to do just doesn’t fit. It happened to me a few years ago with GRails, when the validation system was not too good. After spending some time trying to make it work, I finally rewrote it to fit my needs.