backbone.jsとcoffee scriptを組み合わせた小さいサンプル

2011.12.30

backbone + coffee scriptで快適に

最近は仕事でもJavaScriptの使用頻度が多くなっており、煩雑になりがちでした。 解決方法を探していたところ、backbone.jsというフレームワークが良いらしいという話が出てきたので試してみます。 また、coffee scriptを組み合わせ、シンプルなサンプルを作成してみます。

backbone.jsとは

backbone.jsはDocumentCloud(underscore.jsも開発しているところ)が開発しているMVCフレームワークです。 これを使用すればモデルの操作、HTMLレンダリング、URLフラグメントに応じたルーティング処理を分割して綺麗に記述することができます。 公式サイト ※1やソースコード解説 ※2があるので、詳細はこちらを確認してみてください。 まずはこれだけを用いてサンプルプログラムを作成してみましょう。

backbone.jsだけを用いた小さなサンプル

まず、githubにソースコードや依存ライブラリも含めておいてあるので取得します。

% git clone https://github.com/documentcloud/backbone.git

取得してきたソースにはサンプルプログラムもついており、TODOの操作ができます。ソースコード解説 ※2はこれをベースに解説していますので、 解説とソースを確認すればだいたいの動作が理解できると思います。 まずはこのサンプルよりも小さな、ボタンを押すと入力した文字列が追加されるだけのサンプルを作成します。 適当なディレクトリを作成し、その中にlibディレクトリを作成します。 そして取得したソースのtest/vendorディレクトリ内にある依存ライブラリをコピーします。

次にメイン処理となるtodo.jsファイルを作成します。

/* todo.js */

function() {
//////////////////////////////////////
//
// モデル定義
//
//////////////////////////////////////
var Todo = Backbone.Model.extend({
    //インスタンス生成時に実行
    initialize:function () {
        console.dir("Todo#initialize");
    }
});

//////////////////////////////////////
//
// コレクション定義
//
//////////////////////////////////////

var TodoList = Backbone.Collection.extend({
    model:Todo
});


//////////////////////////////////////
//
// ビュー定義
//
//////////////////////////////////////
var TodoView = Backbone.View.extend({
    //Viewが管理するDOMイベント
    el:"#todoDiv",
    events:{
        // #todoDiv要素以下のbuttonにclickイベントを登録する
        "click button":"addTodo"
    },
    //インスタンス生成時に実行
    initialize:function () {
        console.dir("TodoView#initialize");
        this.collection = new TodoList();
        // collectionに対し、addされたらrenderを実行する
        this.collection.bind("add", this.render, this);
    },
    render:function (todo) {
        $(this.el).children("ul").append(this.template(todo));
    },

    //ボタンがクリックされたらこの関数が実行される
    addTodo:function () {
        var todo = new Todo({content:this.$("#new-todo").val()});
        this.collection.add(todo);
    },
    //追加するHTMLを返す
    template:function (todo) {
        return "<li>" + todo.get("content") + "</li>";
    }
});

var view = new TodoView();

});

htmlファイルを作成します。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1">
    <title>Todo</title>
    <script type="text/javascript" src="lib/underscore-1.2.2.js"></script>
    <script type="text/javascript" src="lib/jquery-1.6.4.js"></script>
    <script type="text/javascript" src="lib/json2.js"></script>
    <script type="text/javascript" src="lib/backbone.js"></script>
    <script type="text/javascript" src="todo.js"></script>
</head>
<body>
<div id="todoDiv">
    <input type="text" id="new-todo"/>
    <button>TODO登録</button>
    <ul>
    </ul>
</div>
</body>
</html>

ブラウザで開いてみてください。ボタンを押すと入力した文字列が登録されていきます。

coffee scriptで書いてみる

次に、いま作成したサンプルをcoffee scriptで記述してみます。 まずはcoffee scriptのコンパイラをインストールしましょう。(homebrewを使用)

$ brew install coffee-script

先ほど作成したtodo.jsをcoffee scriptに置き換えます。todo.coffeeという名前で下記のように記述してください。

# todo.coffee
jQuery ->

  ##################################
  #
  # モデル定義
  #
  ##################################
  class Todo extends Backbone.Model
    initialize:->
      console.dir("Todo#initialize")

  ##################################
  #
  # コレクション定義
  #
  ##################################
  class TodoList extends Backbone.Collection
    model:Todo

  ##################################
  #
  # ビュー定義
  #
  ##################################

  class TodoView extends Backbone.View
  # Viewが管理するDOMイベント
    el:"#todoDiv"

    #todoDiv要素以下のbuttonにclickイベントを登録する
    events:'click button':'addTodo'

    #インスタンス生成時に実行
    initialize:->
      console.dir("TodoView#initialize")
      @collection = new TodoList
      #collectionに対し、addされたらrenderを実行する
      @collection.bind "add", @render, @

    #render
    render:(todo) ->
      $(@el).children("ul").append(@template(todo))

    #ボタンがクリックされたらこの関数が実行される
    addTodo:->
      todo = new Todo({content:$("#new-todo").val()})
      @collection.add todo

    #追加するHTMLを返す
    template:(todo) ->
      "<li>" + todo.get("content") + "</li>"

  #ビューをインスタンス化
  todo_view = new TodoView

ファイルを記述したらコンパイルします。

$ coffee -c todo.coffee

これでtodo.jsファイルが生成されました。ブラウザで確認してみてください。 先ほどと同じように動作します。

まとめ

今回はbackbone.jsとcoffee scriptを使って、小さなサンプルを作成しました。 普通にjavascriptだけを使用するより、シンプルな記述で綺麗に書けそうですね。

参考サイトなど