Join our team!

We're looking for mid-level and senior software developers who love working throughout the stack, and have a track record for designing, building, shipping, and supporting web services and applications. Ideal candidates love Ruby, Rails and Ember, and using BDD and agile processes to ship working software quickly! Experience with Redis, Postgres, RabbitMQ, and ElasticSearch are a huge plus!

Learn more about our mission by visiting IoraHealth.com and by following @IoraHealth.

You're Doing it Right: Defining Explicit Objects in Views

I’m going to start my blogging here at Iora by starting a little series on “best practices” we’ve discovered while building applications with Backbone.js. Since my web series on behavior driven development is already named “YOU’RE DOING IT WRONG” I think I’d like to focus a little bit more on the positive. Backbone is such a new framework that we’re all going to make mistakes here and there, but we should strive to learn and apply some solid development principles.

As a light intro to this series, I’d like to talk about a practice that I’ve started using on the view layer. I’ve begun explicitly naming each object passed into a view initializer instead of using the available ‘model’ object. Let me demonstrate with a bit of code:

Namespace.Views.Users.Show = Namespace.Views.CompositeView.extend({
  initialize: function(options) {
    this.user = options.user;
  },

  render: function() {
    $(this.el).html(JST['users/show']({ user: this.user }));
    return this;
  }
});

This would be instantiated with a router something along these lines:

Namespace.Routers.Stories = Support.SwappingRouter.extend({
  routes: {
    "users/:id":  "show"
  },

  show: function(id) {
    user = Namespace.users.get(id)
    var view = new Namespace.Views.Users.Show({ user: user });
    this.swap(view);
  }
});

The generally accepted pattern for Backbone.js development is to instead use the model object, saving yourself the initialization step. Being slightly more explicit helps out as you expand functionality to the views. Let’s say we want to add the user’s most recent post:

Namespace.Views.Users.Show = Namespace.Views.CompositeView.extend({
  initialize: function(options) {
    this.user = options.user;
    this.recentPost = options.recentPost;
  },

  render: function() {
    $(this.el).html(JST['users/show']({ user: this.user,
                                        recent_post: this.recentPost }));
    return this;
  }
});

If we went with the path of least resistance the implementation could be this instead:

Namespace.Views.Users.Show = Namespace.Views.CompositeView.extend({
  render: function() {
    $(this.el).html(JST['users/show']({ user: this.model,
                                        recent_post: this.options.recentPost }));
    return this;
  }
});

This certainly does get the job done, but I’m not convinced it is more readable code. Furthermore, I’m encouraged to continue to use the this.options to render additional objects passed in, which smells of a Law of Demeter violation to me. Of course, this is a pretty small and insignificant code example, this pattern becomes increasingly valuable when you have a chain of composite views.