A Backbone Lightbox

I’ve been working on making my UI stateless. Here’s a Backbone Lightbox that I made for the current project I’m working on at Airbnb: https://github.com/h4rry/backbone-lightbox

I like how this turned out. I don’t feel like I have to read through the whole thing to understand how the lightbox works. The LightboxModel has everything I need to know about my lightbox state, and the Lightbox View is responding to user input and changes on the model.

Super clean. I’ll do a longer, better write-up later. Just wanted to get this out there real quick.

BackboneConf 2012

My Slides: https://speakerdeck.com/u/hshoff/p/airbnbs-journey-into-mobile-web-backboneconf-2012

I had the pleasure of speaking at the first ever BackboneConf, a wonderful conference put on the by the lovely folks at Bocoup.

Take aways from the conference:

  • Lots of folks are working on making application development easier
  • Everyone is dealing with the same problems and limitations
  • Keep state out of your Views, they should be responding to events coming from Models and user input only
  • Backbone has an awesome community of really smart people
  • Everyone just wants to hear how other people are doing things
  • There’s no one “right way” and that’s okay
  • People were really interested in Airbnb’s i18n problem/solutions

Underscore Matchers for Jasmine

Super helpful set of matchers if your using Jasmine to test your Backbone apps by @raganwald:

expect(snafu).toInclude('s', 'n', 'a')

// if snafu is an array, this is equivalent to:
expect(
  _(snafu).include('s') && _(snafu).include('n') && _(snafu).include('a')
).toBeTruthy()

// if snafu is a Backbone.js collection, this is equivalent to:
expect(
  snafu.include('s') && snafu.include('n') && snafu.include('a')
).toBeTruthy()

Source: https://github.com/raganwald/Underscore-Matchers-for-Jasmine

DOMQL

So this is pretty cool:

DQL is not a fully-fledged programming language but a small DSL inspired by SQL aimed at easing DOM manipulation for DBAs.

Some Examples:

SELECT DIV FROM BODY WHERE ID='container'
UPDATE (SELECT H1 FROM (SELECT DIV FROM BODY).ALL) SET CLASS='active' WHERE CLASS='disabled'

Source: http://amasad.github.com/DOMQL/

Backbone Collections with Polymorphic Models

Cool Backbone thing of the day, you can have polymorphic models inside of a collection!

var Library = Backbone.Collection.extend({

  model: function(attrs, options) {
    if (condition) {
      return new PublicDocument(attrs, options); 
    } else {
      return new PrivateDocument(attrs, options);
    }
  }

});

source: https://github.com/documentcloud/backbone/issues/793#issuecomment-3205062

This wasn’t immediately obvious from reading the Backbone docs:

model   collection.model 
Override this property to specify the model class that the collection contains. If defined, you can pass raw attributes objects (and arrays) to addcreate, and reset, and the attributes will be converted into a model of the proper type.

var Library = Backbone.Collection.extend({
  model: Book
});

This does become obvious when you take a look at the annotated source

var Collection = Backbone.Collection = function(models, options) {
  //...
  if (models) this.reset(models, {silent: true, parse: options.parse});
}

// Backbone.Collection.reset calls Backbone.Collection.add
this.add(models, _.extend({silent: true}, options));

// and Backbone.Collection.add calls Backbone.Collection._prepareModel
if (!(model = models[i] = this._prepareModel(models[i], options))) {
  throw new Error("Can't add an invalid model to a collection");
}

// and _prepareModel is where the good stuff happens
_prepareModel: function(model, options) {
  options || (options = {});
  if (!(model instanceof Model)) {
    var attrs = model;
    options.collection = this;
    model = new this.model(attrs, options);
    if (!model._validate(model.attributes, options)) model = false;
  } else if (!model.collection) {
    model.collection = this;
  }
  return model;
},

// the important line is here:
model = new this.model(attrs, options);

This means that Collection.model can be a Backbone.Model or a function that returns a Backbone.Model.

If you want to play around with the basic idea in the console, try this:

// create a function a couple mock models
function coolModel(){}
function notCoolModel(){}

// test simulates Backbone.Collection.model
var test = function(){
  if (true) {
    return new coolModel();
  } else {
    return new notCoolModel();
  } 
}

// create a new test model
var testModel = new test();

// check to see if it works
testModel instanceof coolModel // => returns true

Crockford’s JSCheck Tool

The prolific Douglas Crockford has a new tool out called JSCheck.

JSCheck is a specification-driven testing tool. From a description of the properties of a system, function, or object, it will generate random test cases attempting to prove those properties, and then report its findings. That can be especially effective in managing the evolution of a program because it can show the conformance of new code to old code. It also provides an interesting level of self-documentation, because the executable specifications it relies on can provide a good view of the workings of a program.

- Douglas Crockford

He proposes writing specs (he calls them checks) in the source file in comment blocks. JSCheck is a special tool that can find these comment blocks and run your checks. During minification all comments get removed, so the checks are no where to be found in production code. 

Of course this is a solved problem with JS testing tools like Jasmine, Mocha, etc. because specs are never served from /public so no one ever sees them in production. 

One drawback to this comment-code-checker is you lose syntax highlighting in commented blocks, so readability goes away.

Sacrificing syntax highlighting might be worth it for folks that dislike having to switch between files while writing specs. Using comments to describe and check the function is a good idea and I’m happy that someone explored it to the finish.

In the end, it comes down to whatever what your most comfortable work flow is.

Just make sure your work flow includes writing specs.

Backbone Meet Rails

A great presentation from Sarah Mei on using Backbone with Rails.

This is a pattern that I see a lot in new, greenfield Rails applications. It’s essentially “Rails as an API,” and what it means is that in most new Rails apps, we do no server-side HTML rendering at all. Instead we build a server that just serves data, usually in the form of JSON, and we leave it up to the JavaScript to render all the markup that the user sees.

- Sarah Mei

http://speakerdeck.com/u/sarahmei/p/using-backbonejs-with-rails

Previous pageNext page
Back to top