孤独プログラマー譚

孤独死が近い。

Backbone.jsで超シンプルなMVCを書く

前回はピュアなJavaScriptでシンプルなMVCを書くという趣旨でしたが…
フレームワークを使った方がシンプルに書けるのでは?」
という考えが巡り始めたので、今回は前回の内容をBackbone.jsで書き換えます。

Backbone.jsを簡単に説明すると…
日本語に訳して「背骨」なだけあって、MVCの枠組みだけを提供してくれます。
jQueryと共存できる…というか、Backbone.jsのライブラリ自体がjQueryに依存してます。
要は、大枠はBackbone.jsがやるから、細かいことはjQueryでやってくれってことです。

■ Model

var Model = Backbone.Model.extend({
    buttonStatus: true,
    changeData: function() {
        if (this.buttonStatus) {
            this.buttonStatus = false;
        } else {
            this.buttonStatus = true;
        }
        this.trigger('changingIsDone');
    }
});
var model = new Model;

まずモデル。データは全部モデルに持たせます。
モデルからDOM操作は行いません。

this.trigger('changingIsDone');

データに変更があれば、モデルの「changingIsDone」イベントが発火されます。
※HTMLの各要素から発火されるイベント(onclick, onchange等)とは別の概念と思われます。

■ View

var View = Backbone.View.extend({
    el: 'body',
    events: {
        'click button': 'switchButtonName',
    },
    initialize: function() {
        this.listenTo(this.model, 'changingIsDone', this.render);
        this.render();
    },
    switchButtonName: function() {
        this.model.changeData();
    },
    render: function() {
        var buttonName;
        if (this.model.buttonStatus) {
            buttonName = '乃木坂46';
        } else {
            buttonName = '欅坂46';
        }
        $('button').text(buttonName);
    },
});
var view = new View({ model: model });
events: {
    'click button': 'switchButtonName',
},

イベントハンドラを登録してます。
switchButtonNameメソッドから、モデルを操作してます。

initialize: function() {
    this.listenTo(this.model, 'chngingIsDone', this.render);
    this.render();
},

initializeメソッドはPHPの__construct()のようなものです。
listenToメソッドで、モデルの「chngingIsDone」イベントの監視を開始しました。
「chngingIsDone」イベントが発火すると、自動でrenderメソッドが実行されます。

render: function() {
    var buttonName;
    if (this.model.buttonStatus) {
        buttonName = '乃木坂46';
    } else {
        buttonName = '欅坂46';
    }
    $('button').text(buttonName);
},

renderメソッドではDOM操作を行っています。


ここで面白いのは、モデルの「changingIsDone」イベントを監視できるViewを複数追加できることです。

■ View 2

var SubView = Backbone.View.extend({
    el: 'p',
    initialize: function() {
        this.listenTo(this.model, 'changingIsDone', this.render);
        this.render();
    },
    render: function() {
        var description;
        if (this.model.buttonStatus) {
            description = '2011年に結成されました。';
        } else {
            description = '2015年に結成されました。';
        }
        $(this.el).text(description);
    },
});
var subView = new SubView({ model: model });

こちらのViewもモデルを監視しています。
つまり、モデルに変化があれば、View, SubViewの両方がレンダリングされる…ということです。

<body>
<button></button>
<p></p>
</body>

こちら、HTML。


ピュアなJavaScriptより、こちらの方がシンプルに書けました。
デメリットは、そのフレームワークの経験者でないと、システムの修正を気軽にできないことでしょうか…。