Close
Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

LABS
Feature hydra: how many heads does your product have?

Should a web and iOS project have one or two tracks/teams/IPMs?

I posted that question to our internal Q&A forum a few months ago.  We were kicking off a client on a large project, building multiple applications for web (incl. mobile) and iOS.

Read more »

LABS
How to render jade templates on the server

The best way for Google and friends to crawl and index a page is by finding static content. With applications that make heavy use of libraries like Backbone, Sproutcore or ember.js a lot of the content can be rendered in the browser.

Read more »

LABS
Hunting Memory Leaks in Backbone

Ever notice your backbone app slows down considerably after using it for a few minutes? Or maybe your event callbacks are called more than once each time the event fires? Or my favorite, Chrome runs out of memory if you have a few tabs open that have run your entire Jasmine suite? This means you have backbone leaks.

I just spent the last week hunting these down in a very large app. It turns out the problem is tractable with a few guidelines. None of this is ground-breaking, but I wanted to put it all in one place.

1) The object retaining tree in the Chrome heap profiler is amazing. Use it.

LABS
Shorthand for searching a View's DOM in Backbone

Sometimes you use a pattern so frequently that you don't realize that other people might not know about it. Here's the most recent one for me -- I was surprised that this wasn't being used in the last few codebases I've seen:

If you're using Backbone.js, instead of writing

view.$el.find('span.timestamp')

or worse

$(view.el).find('span.timestamp')

or

$('span.timestamp', view.$el)

Backbone provides a $ method such that you can simply write

view.$('span.timestamp')

It's less to type and it doesn't hurt readability.

LABS
Cocktail: DRY up your backbone code with mixins

I've continued to enjoy using Backbone.js to build single page apps. As I've seen more and more real world backbone I've started to develop opinions to augment the blissfully unopinionated little framework that could.

One of these opinions has turned into a mini-library: Cocktail adds functionality to Backbone's extend to facilitate breaking up reusable code into mixins. It's pretty straightforward:

  1. Define your mixin. Mixins are just plain vanilla JavaScript objects with methods and properties hanging off of them. Here's a slightly contrived mixin that makes a view selectable:

    window.MyMixins = {};
    MyMixins.SelectMixin = {
      initialize: function() {
        this.model.on('change:selected', this.refreshSelect, this);
      },
    
    
      events: {
        click: 'toggleSelect'
      },
    
    
      render: function() {
        this.refreshSelect();
      },
    
    
      refreshSelect: function() {
        this.$el.toggleClass('selected', this.model.get('selected'));
      },
    
    
      toggleSelect: function() {
        this.model.set('selected', !this.model.get('selected'));
      }
    }
    
  2. Mix your mixin into your views. It's a one-liner:

    var MyView = Backbone.View.extend({
      mixins: [MyMixins.SelectMixin, MyMixins.SomeOtherMixin],
    
    
      events: {
        'click .myChild': 'myCustomHandler'
      }
    
    
      initialize: function() { ... },
      render: function() { ... },
      etc...
    });
    
  3. That's it! Instances of MyView will automatically inherit the behaviors and methods defined in SelectMixin.

Cocktail brings two simple things to the table:

  • it adds the special mixins:[...] notation to Backbone's extend.
  • it automatically detects and handles method collisions. In the example above Cocktail will wrap MyView's and SelectMixin's implementations of initialize into one method and assign that method to the new, composite, class. The return value of this composite method is the last non-undefined value returned by the methods it wraps. All colliding methods are handled this way, as is the events hash (the events hashes all get merged together).

There are more details and examples at the repo. In particular, there's an example for testing mixins with Jasmine -- it goes over a pattern for writing shared behaviors in Jasmine.

LABS
Jasmine Testing: Param(s) passed to a method.

Recently, I've been using a nice way to test if the correct arguments have been passed to a method. This uses a neat property of jasmine where you set up the method you want to test as a mock and have an expectation inside the mock.

The only caveat is you have to set an expectation that your mock get's called, otherwise if it never gets executed the test will also never fail.

LABS
Simplifying View-View Events in Backbone using the Mediator Pattern

In most single-page apps, you will inevitably end up having multiple views on one page at a time. It usually starts out with just one view, and then that view needs to bind to events on a subview, and then the subview gets its own subview who will also trigger events that affect the top-level view...

When you have one view that ties to one model, the standard way to set up the binding in Backbone looks something like

MyView = Backbone.View.extend({
  initialize: function() {
    this.model.bind("change:someProp", this.render, this);
  }
  // ...
});

You might later find yourself binding view events in the same way:

MySubView = Backbone.View.extend({
  events: {
    "click li.foo": "fooSelected"
  },

  fooSelected: function(e) {
    this.trigger("foo:selected", new Foo({id: $(e.target).data("fooId") }));
  }
  // ...
});

MyView = Backbone.View.extend({
  initialize: function() {
    this.model.bind("change:someProp", this.render, this);
    this.subview = new MySubView();
    this.subview.bind("foo:selected", this.addFoo, this);
  },

  addFoo: function(foo) {
    var fooView = new FooView({model: foo});
    fooView.bind("someOtherEvent", this.render, this);
    this.$(".foos").append(fooView.render().$el);
  }
  // ...
});

This can get out of hand rather quickly in several ways:

  • You have to add a lot of code to your view to just to wire up the events properly, and your view has to be very aware of specific subviews
  • If you have three or more levels of views, then the views in the middle may need to "forward" events between subviews and parent views
  • You can end up binding the same method to the same event on subviews of the same class
  • To test that the events are configured correctly, you will need to instantiate all of the necessary subviews in your tests

In my experience, one of the cleanest solutions to this problem is to apply the mediator pattern.

(To be fair: it would be better if we could avoid needing a mediator altogether, but that is often not a realistic goal.)

LABS
Coccyx: plug up those backbone leaks

A number of projects at Pivotal have been using Backbone.js to build single page web apps. I've enjoyed using Backbone: it's lightweight, unopinionated, helps encourage good separation of concerns between models and views, and reduces a fair bit of JavaScript boilerplate by bringing just enough framework to the table.

Unfortunately, it's very easy to write Backbone code that leaks - especially in the view layer. A common backbone pattern is to set up some event bindings for a view:

var MyView = Backbone.View.extend({
    initialize: function() {
        this.model.on('change', this.update, this);
        this.someOtherModel.on('change', this.update, this);
        this.boundResizeHandler = _.bind(this.resizeHandler, this);
        $(window).on('resize', this.boundResizeHandler);
    },
    ...etc..
});

If your app needs to switch between several such views it is not enough to simply remove the view's DOM and null out any references to the view. You must also unbind these event bindings in order for the view to be garbage collected. Moreover, if this view contains any subviews, you must also tear down all event bindings for all its subviews. If you do not succesfully clear out all bindings the view (and/or its subviews) will leak.

What's worse: while there are some great tools out there to identify leaking objects, Backbone's default constructor lists all objects as type child. This makes finding the leaky Backbone objects that are instances of MyView nearly impossible in Chrome's heap propfiler.

Coccyx attempts to adress these problems by doing two things:

  1. Coccyx adds named constructors to Backbone. You no longer need to wonder which child is yours. By adding constructorName when you extend a Backbone class you'll be able to easily tell which object is which in the console and the heap profiler.

  2. Coccyx implements teardown-able view hierarchies. You can easily build view hierarchies in which parents are aware of their children and can tear the entire structure down by calling tearDown() on a root node. tearDown() automatically unbinds any Backbone event bindings, cleans up DOM events and gives your view a chance to perform any custom teardown via a callback.

There are many more details at https://github.com/onsi/coccyx. Bug reports and pull requests are encouraged!

LABS
A convenient 'super' method for Backbone.js

Inheritance in Backbone

Backbone.js comes with a minimalist OO inheritance framework similar to the one employed by CoffeeScript. Each base class has a static method called extend that is used to create a subclass, like this:

User = Backbone.Model.extend({
  // instance methods
},
{
  // class methods
});

extend returns a constructor whose prototype inherits from Backbone.Model.prototype. References to all of Backbone.Model's static methods and properties (including extend) are copied to the new constructor.

Calling 'super'

The constructor also receives a __super__ property, which references its superclass.

User.__super__ === Backbone.Model.prototype

This makes it possible to call super inside of a class or and instance method:

User.prototype.save = function(attrs) {
    this.beforeSave(attrs);
    User.__super__.save.apply(this, arguments);
};

CoffeeScript has a super keyword that compiles to the line above, but when using Backbone with plain javascript, its a little grating to have to type that out.

A small layer of convenience

I wrote this little super method (test-driven using jasmine) which saves me having to repeat the constructor's name all over the place. You call it like this:

User.prototype.save = function(attrs) {
    this.beforeSave(attrs);
    this._super("save", arguments);
};

The second parameter to _super is the array of arguments to pass to the overridden method. This is to optimize for the common case of passing the arguments object straight through.

There's no way to avoid having to repeat the method name like that, unless you wrap every method definition with a helper function that either passes the overridden method as a parameter (a la Prototype.js) or reassigns a hidden super property behind the scenes (like JS.Class or John Resig's approach). These approaches won't work with Backbone's ultra-minimalist inheritance system.