Zack Hubert

Batman.js Mixins

Over the last several months, I’ve been building an ambitious Batman.js and Rails app (it’s going great!). In the course of things, I needed a way to group similar functionality like I would in a concern-based module in Rails. The mixin fits the bill perfectly.

Let’s say you have several Batman models that all have some attributes that share something in common, like maybe they have a common accessor to deal with an excessively terse status code:

app/assets/javascripts/batman/models/foo.js.coffee
1
2
3
4
5
6
7
8
9
class Foo extends Batman.Model
  @encode 'status_code'
  @accessor 'status_to_s',
    get: ->
      switch @get('status_code')
        when "G" then "Geddy"
        when "L" then "Lifeson"
        when "P" then "Peart"
        else "Disregard"

Well, if Foo and Bar both need accessors like this, a mixin will enable you to share the code between them.

To start, I create a mixins directory at app/assets/javascripts/batman/mixins and then require it before my models, like so:

app/assets/javascripts/application.js.coffee
1
2
3
4
#= require app
#= require_tree ./batman/mixins
#= require_tree ./batman/models
#= require_tree ./batman/controllers

Then I can create the first mixin like so:

app/assets/javascripts/mixins/status_code_mixin.js.coffee
1
2
3
4
5
6
7
8
9
10
App.StatusCode =
  initialize: ->
    @encode 'status_code'
    @accessor 'status_to_s',
      get: ->
        switch @get('status_code')
          when "G" then "Geddy"
          when "L" then "Lifeson"
          when "P" then "Peart"
          else "Disregard"

And include it in Foo and Bar with:

app/assets/javascripts/batman/models/foo.js.coffee
1
2
class Foo extends Batman.Model
  @classMixin App.StatusCode

Couldn’t be easier to keep things DRY.

Of course, there are many ways to reduce code duplication and this is just one, but hopefully it helps you as much as it did me.

Comments