console.lealog();

@leader22のWeb系に関する勉強めもブログですのだ

0からはじめるBackbone.js Part.2

まずはModel編。
公式にあるModelの部分を読む。

Modelとはなんぞ

取り扱うデータの最小単位って覚えることにした。
CDアルバムなら曲、学校なら(学年・クラスがあって)生徒、とか。

で、ただのデータ構造そのものではなくそのデータを変更するとか状態を取得するとか、自分に関することはなんでも。
上手く言葉にできないのですが、そういうものらしい。

Backbone.jsのModel

だいたいあってる!(たぶん

Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control.

さて。
公式によると、Modelに定義されてるのは以下。
多いw

  • extend
  • constructor / initialize
  • get
  • set
  • escape
  • has
  • unset
  • clear
  • id
  • idAttribute
  • cid
  • attributes
  • changed
  • defaults
  • toJSON
  • sync
  • fetch
  • save
  • destroy
  • validate
  • validationError
  • url
  • urlRoot
  • parse
  • clone
  • isNew
  • hasChanged
  • changedAttributes
  • previous
  • previousAttributes

まぁ暗記する必要はないと思うので流す。

Modelを作る

  • extend
  • constructor / initialize
var Song = Backbone.Model.extend({
	initialize: function(){
		// Model has created!
	}
});

var mySong = new Song({
	title: 'My first song',
	author: 'leader22',
	description: '<em>Awesome!</em>'
});

extendでModelを作る。
initializeで初期化処理。

Modelの値を取得、変更する

  • get
  • set
  • escape
  • has
mySong.get('title');// 'My first song'

mySong.set('title', 'My very first song');

mySong.escape('description');// '&lt;em&gt;Awesome!&lt;&#x2F;em&gt;'

mySong.has('author');// true

ちなみにset時には、Modelのchangeイベントが発火(正確にはModelのchangeとModelの変更があったAttrのchange)。
発火させたくないときは、

mySong.set('title', 'My very first song', {silent: true});

のようにオプションを指定。

Modelの値を削除する

  • unset
  • clear
mySong.unset('title');

mySong.clear();

clear()してもインスタンスが消えるわけではないみたい。

Modelのもつ情報(識別子系)

  • id
  • idAttribute
  • cid

id

なにしたら付与できるんかと思ったら、後述のsave()した結果のレスポンスがあって初めて付くそうな。

参考:How to generate model id's with Backbone.js - Stack Overflow

idAttribute

上記idとは別に、一意な識別子が欲しい場合に使うそうな。

cid

Modelのインスタンスができる度に増える一意の値。

var song1 = new Song();// cid = "c1"
var song2 = new Song();// cid = "c2"
var song3 = new Song();// cid = "c3"

「上記idがあるやつ=サーバーに保存済み」のように判別する時に使えるとのこと。

Modelのもつ情報(そのもの系)

  • attributes
  • changed
  • defaults
  • toJSON
mySong.attributes;
/*
{
	title: "My first song",
	author: "leader22",
	description: "<em>Awesome!</em>"
}
*/

mySong.set('title','Wahoo');
mySong.changed;
/*
{
	title: 'Wahoo'
}
*/

今さらですがModelには初期値を設定可能。

var Song = Backbone.Model.extend({
	initialize: function(){
		// Model has created!
	},
	defaults: {
		title: 'No name',
		author: 'Various artists',
		description: 'Some text...'
	}
});

上記attributesを一気に取りたいときは、

mySong.toJSON();
/*
{
	title: "My first song",
	author: "leader22",
	description: "<em>Awesome!</em>"
}

実際にはJavaScriptのオブジェクト(≠json)が取得できちゃう。
きちんとしたjsonが欲しい場合は、
*/
JSON.stringify(mySong);

Modelの値をサーバーとやり取りする

  • sync
  • fetch
  • save
  • destroy

ここをきっちりやらんとダメな気がするものの、まだ全然試せてないので箇条書きで・・。

sync

手元のModelの状態を、サーバー側と同期する。
Backbone.syncと同じで、コレはサーバーサイドと値をやり取りすると必ず実行されてるやつ。
ここに処理を書いて、データの保存時を監視・・とかできる。

fetch

手元のModelの状態を、サーバー側のもので最新化する。

save

mySong.save();// まるっと
mySong.save({'title', 'My new song'},{patch: true});// 一部だけ

手元のModelの状態を、まるまるサーバー側にPushする。
まるっとしたくないときは、patchにする。

Modelにvalidateのロジックが書かれていれば処理される。
バリデーションに失敗すると、データの保存は実行されない。

mySong.save({
	success: function(){},// 成功時のコールバック
	error: function(){}// 失敗時のコールバック
});

コールバックも指定可能。

destroy

Modelの削除をする。

mySong.destroy({
	success: function(){},// 成功時のコールバック
	error: function(){},// 失敗時のコールバック
	wait: true// サーバー側からのレスポンスを待って、上記コールバックを実行したい場合にtrue
});

Modelの値のバリデーション

  • validate
  • validationError

バリデーションには、2段階のステップが必要。
1. validateのロジックを書く
2. invalidイベントを拾う

var Song = Backbone.Model.extend({
	initialize: function(){},
	validate: function(attrs, options) {
		if (attrs.title === '') {
			return 'No title!';
		}
	}
});

var mySong = new Song();
mySong.on('invalid', function(model, error){
	alert(error);
});

mySong.save({title, ''});// 'No title!'

単純に文字列を返せばエラー認定になる。
ちなみにこのバリデーションはsave()の時には呼ばれるけど、set()の時には呼ばれない。
set()時にも使いたいなら、{validate: true}をオプションで渡す。

mySong.set({title, ''}, {validate: true});// 'No title!'
簡単なパターン表
method addValidateOption? invalidEventFired? dataSaved?
set() false no yes
set() true fire no
save() false fire yes
save() true fire no

データの所在系

  • url
  • urlRoot
  • parse

url / urlRoot

本来Modelはサーバー側に保存されるデータ。
よって、URIとしてどこにあるのかを扱うメソッドがこれら。

parse

save()やfetch()など、サーバー側からデータを取得した際に実行される。

使ってみないとわからない系ですね。

その他のユーティリティそのいち

  • clone
  • isNew

clone

var myCopy = mySong.clone()

そのまんま。

isNew

上記の通り、Modelのidはサーバー側に保存したら付与されるもの。
そのidの有無でもって、true/falseを返す。

その他のユーティリティそのに

  • hasChanged
  • changedAttributes
mySong.on("change", function() {
  if (mySong.hasChanged("title")) {
    // ...
  }
});

前回のchangeイベントから、何か変更があったかどうかを捕捉する。
changeイベントが起こって、その中でさらに処理を分岐したい場合に使うらしい。
changedAttributesはその名の通り、変更のあったAttrを取得できる。

  • previous
  • previousAttributes

こちらも同じくchangeイベントが起こって、その中でさらに処理を分岐したい場合に。
これはchangeされたAttrのchangeされる前を取得できる。

所感

なんというか、できることはスッキリしていてわかりやすいと思う。
やっぱり試されるのは設計力ってやつか・・。