yutaponのブログ

javascript界隈の興味あるネタを備忘録的に残しておく場所

Backbone.jsに入門してみる【Model編】

今日はBackbone.Modelについてです。
Backbone.Collectionはあまり使ったことがないので、また別で扱います。

Backbone.Modelとは

Modelといえば、MVCのMのことです。
DBから値を得たり、表示用に加工したり、ロジックを書いたりします。
注意したいのがDOM操作は行なわいということ。
DOM関連の処理はBackbone.Viewに集約して、
DOMとは関係のないロジックをBackbone.Modelに書くようにします。
これはメンテナンス性を上げるためにそうしたほうが良いということです。


Backbone.Modelの使い方

まずはBackbone.Modelを拡張して独自のモデルを作ります。
モデルを作ったらインスタンス化して使っていきます。

例として電話帳を考えてみます。
電話帳は電話番号に紐づく情報の集合からなっている気がするので、
まずは1件あたりの情報をモデルに落とします。

var Address = Backbone.Model.extend({
    defaults: {
        language: 'jp'
    },
    initialize: function(){
        _.bindAll(this);
        this.on('initialize', this.setRegisterDate);
        this.trigger('initialize');
    },
    setRegisterDate: function(){
        this.set('registerDate', new Date());
    }
});
var address1 = new Address({
    name: 'ゆたぽん',
    tel : '090-xxxx-xxxx',
});
var address2 = new Address({
    name: 'yutapon',
    tel: '080-xxxx-xxxx'
});

ぱっと見で処理の流れを追えたでしょうか?
モデルが管理するデータのことを属性(attributes)といいます。
属性を追加したり、参照したりはset(key, value), get(key)で行えます。
これさえ覚えていれば何となくわかるかもしれません。

defaults ?

defaultsにはオブジェクトかオブジェクトを返す関数を指定でき、
インスタンス共通で持つ属性を設定します。
とりあえずこの電話帳は日本で使われることを想定しているということで、
language: 'jp' としました。

defaultsでの注意点

address1.get('language')とすると、'jp'を取得できるのですが、
address2.set('language', 'en')とした後に、address1.get('language')を
行うと'en'が返るようになります。
すべてのインスタンスが一つのオブジェクトを参照しているのですね。

これを防ぐにはdefaultsにオブジェクトを返す関数を設定します。
例えばこんな感じです。

defaults: function(){
    return {
        language: 'jp'
    };
}

これで一つのオブジェクトへの参照を持たなくなるので、
defaultsで設定した属性の値を変更しても他のインスタンスへの影響はなくなります。
インスタンスで共通して持ちたい場合もあるので、場合によって使い分けましょう。

initialize ?

initializeメソッドはモデルがインスタンス化されるときに実行されるメソッドです。
new Address()をした時に実行されているわけですね。

_.bindAll(this)

_.bindAll(this)はunderscore.jsのbindAll()を使って、実行コンテキストを
Adressオブジェクトに固定してます。
今回の例でいうと無くてもいいのですが、後々ハマるかもしれないので書いてます。

this.on('initialize', this.setRegisterDate)

これはBackbone.Eventsと同じ書き方ですね。
そうです、Backbone.ModelはBackbone.Eventsを継承してます。
他のCollectionやViewなんかも同様です。

このモデル内でinitializeイベントが発火したらsetRegisterDate()を実行する、
というイベントリスナーを設定してます。

this.trigger('initialize')

initializeイベントを発火してます。

setRegisterDate ?

これは自分で作ったメソッドです。
結果として、initializeメソッドの実行時に呼ばれているので
インスタンス生成時(電話情報登録時)の日付を登録しています。

Addressモデルのインスタンス生成

モデルのインスタンス生成時にオブジェクトを渡すと
そのまま属性に追加することができます。


処理の流れをまとめると

  1. インスタンス生成(nameとtel属性をセット)
  2. defaultsの属性をセット
  3. initializeメソッド実行(initializeイベントが発火)
  4. setRegisterDateメソッドが実行

という流れになります。


Backbone.Modelの他のメソッド

escape()

escape()は名前の通り、属性値をエスケープしてXSS対策を施してくれます。
使い方はaddress1.escape('name')みたいに、get()を置き換えて使います。
実際の運用ではテンプレートエンジンの方でエスケープする方が多いですが、
頭の隅の方にでも覚えておいて損はないかと。

has()

指定した属性がモデルに存在するか調べます。

address1.has('name'); // true
address1.has('hogehoge'); // false

unset()

指定した属性をモデルから削除します。

address1.has('name'); // true
address1.unset('name');
address1.has('name'); // false

save()とかそのへんのメソッド

このあたりのメソッドは使ったことがなく、
説明が長くなりそうなので別途どこかで扱います。


おわりに

今回はBackbone.Modelだけになってしまい
内容もかなり簡単なものに・・^^;

Backbone.js関連のネタはBACKBONE.JSガイドブックを見て
復習しながら書いてるので、defaultsまわりは勉強になりました。

次回はBackbone.Collectionの予定です。