リア充爆発日記

You don't even know what ria-ju really is.

Backbone.jsでClassをまたいだ共通処理を扱いたいときのメモ

twitterの「フォローする」ボタン的なものがあって、それはtwitterみたいに色んな画面(View)に登場する。
ボタンの動き自体は、1つのView(MyAPP.View.UserRelationButton)にまとまっているんだけど、こんな感じで、UserRelationButtonの初期化は、DOMから必要情報を拾ってくる必要があるため、ある程度の手順がいる。

  $(@el).find('.js-following-btn').each(->
      options = {}
      options.el = $(this).find('button')
      options.followingId = $(this).data('following-id')
      options.relationId = $(this).data('relation-id') if $(this).data('relation-id')
      new MyAPP.Views.UserRelationButton(options)
    )

これが複数の親Viewで重複して記述されているのでDRYにしたい、といった感じ。

やり方はいろいろあると思うけど、いろいろ調べてみて一番しっくりきたやり方が以下。
http://ricostacruz.com/backbone-patterns/#mixins

ちなみにRailsでbackbone-on-railsを使っている前提なのでエントリ中のJSはぜんぶCoffeeScriptです。

処理を適当なfunctionにまとめる

mixin.js.coffee

MyAPP.Mixins.UserRelationButtonInitializer =
  initializeUserRelationButton: ->
    $(@el).find('.js-following-btn').each(->
      options = {}
      options.el = $(this).find('button')
      options.followingId = $(this).data('following-id')
      options.relationId = $(this).data('relation-id') if $(this).data('relation-id')
      new MyAPP.Views.UserRelationButton(options)
    )
使うところでextendする
class MyAPP.Views.FollowersIndex extends Backbone.View

  el: '#followers-index'

  initialize: ->
    @initializeUserRelationButton()


_.extend(MyAPP.Views.FollowersIndex.prototype, MyAPP.Mixins.UserRelationButtonInitializer)
エントリーポイントのところに追記する

my_app.js.coffee

window.MyAPP =
  Mixins: {} # new!
  Models: {}
  Collections: {}
  Views: {}
  Routers: {}
  initialize: ->


なお、モジュールを記載するファイルは、mixin.js.coffeeとしてあるけど、使う場所より先に読み込まれていればなんでもいいし、そのへんはケースバイケースで工夫すればいいのだと思われ。


以上、よろしくおねがいいたします。