Backbone.js サンプルアプリケーション #4

はじめに

前回の続きです。


var AppView = Backbone.View.extend({
    el: $("#todoapp"),

    statsTemplate: _.template($('#stats-template').html()),

    events: {
        "keypress #new-todo": "createOnEnter",
        "click #clear-completed": "clearCompleted",
        "click #toggle-all": "toggleAllComplete"
    },

    initialize: function(){
        this.input = this.$("#new-todo");
        this.allCheckbox = this.$("#toggle-all")[0];

        this.listenTo(Todos, 'add', this.addOne);
        this.listenTo(Todos, 'reset', this.addAll);
        this.listenTo(Todos, 'all', this.render);

        this.footer = this.$('footer');
        this.main = $('#main')

        Todos.fetch();
    },

    render: function(){
        var done = Todos.done().length;
        var remaining = Todos.remaining().length;

        if(Todos.length){
            this.main.show();
            this.footer.show();
            this.footer.html(this.statsTemplate({done: done, remaining: remaining}));
        }
        else{
            this.main.hide();
            this.footer.hide();
        }

        this.allCheckbox.checked = !remaining;
    },

    addOne: function(todo){
        var view = new TodoView({mode: todo});
        this.$("#todo-list").append(view.render().el);
    },

    addAll: function(){
        Todos.each(this.addOne, this);
    },

    createOnEnter: function(e){
        if(e.keyCode != 13) return;
        if(!this.input.val()) return;

        Todos.create({title: this.input.val()});
        this.input.val('');
    },

    clearCompleted: function(){
        _.invoke(Todos.done(), 'destroy');
        return false;
    },

    toggleAllComplete: function(){
        var done = this.allCheckbox.checked;
        Todos.each(function(todo){
            todo.save({'done':done});
        });
    }
});

var App = new AppView;

コード解説


el: $(“#todoapp”),

elにJQueryオブジェクトを指定しています。前回のliタグのViewクラスと違い、既に存在しているDOMノードを指定しています。


statsTemplate: _.template($(‘#stats-template’).html()),

Underscore.jsのtemplateメソッドです。scriptタグ内に記述してあるHTML文字列をテンプレートとして利用します。


events: {
“keypress #new-todo”: “createOnEnter”,
“click #clear-completed”: “clearCompleted”,
“click #toggle-all”: “toggleAllComplete”
},

イベント定義です。


initialize: function(){
this.input = this.$(“#new-todo”);
this.allCheckbox = this.$(“#toggle-all”)[0];

    this.listenTo(Todos, 'add', this.addOne);
    this.listenTo(Todos, 'reset', this.addAll);
    this.listenTo(Todos, 'all', this.render);

    this.footer = this.$('footer');
    this.main = $('#main')

    Todos.fetch();
},


このビューの初期化処理です。

TodoのコレクションであるTodosのイベントをサブスクリプションします。Todos.fetch();が実行されるとTodosにTodoが格納されてresetイベントが発火しaddAllがコールされて全てのTodoが描画されます。


render: function(){
var done = Todos.done().length;
var remaining = Todos.remaining().length;

    if(Todos.length){
        this.main.show();
        this.footer.show();
        this.footer.html(this.statsTemplate({done: done, remaining: remaining}));
    }
    else{
        this.main.hide();
        this.footer.hide();
    }

    this.allCheckbox.checked = !remaining;
},


描画メソッドです。Todosの状態によってUIを制御します。


addOne: function(todo){
var view = new TodoView({mode: todo});
this.$(“#todo-list”).append(view.render().el);
},

addAll: function(){
    Todos.each(this.addOne, this);
},

createOnEnter: function(e){
    if(e.keyCode != 13) return;
    if(!this.input.val()) return;

    Todos.create({title: this.input.val()});
    this.input.val('');
},

clearCompleted: function(){
    _.invoke(Todos.done(), 'destroy');
    return false;
},

toggleAllComplete: function(){
    var done = this.allCheckbox.checked;
    Todos.each(function(todo){
        todo.save({'done':done});
    });
}


各イベントから呼ばれる処理群です。内容は見ればなんとなく分かると思います。

以上でTodosのコードは終わりです。起点となるビュー(AppView)があり、そこからビュー、コレクション、モデルを利用している構成であることが分かります。
次はrouterやmodelをデータストアと同期するBackbone.sync()について見ていこうと思います。