カテゴリ: Javascript

angular.jsとknockout.jsを使ってみた

とても便利なangular.jsとknockout.js

これまでbackbone.jsを触ってきたのですが、正月休みでangular.jsとknockout.jsも試しに触ってみました。

backbone.jsほど学習に時間がかからず、特にknockoutはdata-bind属性内に予め定義されたバインディングや自作のバインディングを書いて、それにパラメータを渡すことで様々なイベントや処理が行えるようなかんじで、覚えるのがとても楽でした。

angular.jsは ng-hogehoge 属性でhogehogeをいろんな形式に書き換えることで様々なイベントや処理を行うことができるかんじになっており、ng-model属性で定義した識別子をng-valueに書くとその部分にリレーションができて<input data-model=”hoge”>とすると<span ng-value=”hoge”>の値がリアルタイムで書き換わるので便利。

knockout.jsでも同じことはできるけども、knockout.jsの場合は、observableでデータの監視、computedでデータの監視で変化があると実行する関数で明示的に定義してやらないといけないので注意。

backbone.js使わなくてもいいような・・・?

そんなことはないです。backbone.jsは様々なプラグインが用意されており、もしくは自分で自由に振舞いを書き換えることができるのでかなりカスタマイズがきくし自由度が高い。angular.jsやknockout.jsはビューの書き換えには特化してるけどモデルの扱いは弱いので、そういった面でもbackbone.jsは補えたりする。なので、一長一短なのだ。

使い分け

  • backbone.js → 大規模開発に向いている。フルカスタマイズしたい人向けで、骨さえ用意してくれればいいよ!っていう場合これ
  • knockout.js → イベントの処理かくのめんどくさいので楽に書きたい、それだけでいいという方むけ。
  • angular.js → 楽に書きたい! 楽にリッチなWebアプリ作りたい! 細かいカスタマイズは必要ない! という方はこれ!

最後に

どのフレームワークも「癖」みたいなものがあります。食わず嫌いはしないで一度様々なフレームワークに触れてみて自分、もしくはプロジェクトにあったフレームワークに手を出してみるのがいいと思います。

backbone.jsの公式ページを上から下まで眺めてみる

夜です。今回は何を思ったのか、backbone.jsの公式ページを眺めるという行為に及んでみたいと思います。
ちょっと見てみると、backbone.jsのルーティングがなんか便利そうじゃないですか。pushState触らなくていいとか!
ajax使うにはもうbackboneは手放せない存在なんじゃないでしょうか。githubは違うプラグイン使っているみたいですが…

スクリーンショット 2013-08-04 2.18.07
公式ページ。backbone.jsの配布ページとマニュアルページがひとつに繋がっているタイプ。Ctrl+Fで検索しやすいのでなかなかいいかも。

Introduction

Google翻訳を使ってIntroductionを読んでみます。要約すると(確実に翻訳ミスがあります)

  • jQueryをDOMを直接操作してHTMLを動的に動かす開発をしてるんでしょうけど、古いよ
  • フロントエンドとサーバー間でデータの受け渡しに四苦八苦してる
  • Backbone.jsを使うとデータの受け渡し楽よ
  • Backbone.jsを使うとデータに変化が合った場合changeイベントが走って画面が動的に書き換わるから楽よ
  • Backbone.jsを使うと手作業でHTML更新しなくてすむよ
  • Backbone.jsがどういうものなのか下にたくさんサンプルスクリプト用意したから見てね
  • 再生ボタン押すとサンプルスクリプトを直接実行できるよ

という感じな気がする。多分。

Upgrading to 1.0

1.0の変更点などが書いてある。あまり関係なさそうなので省略。

Backbone.Events

イベントは、任意のオブジェクトにイベントドリブンなメソッドを提供したりできるようです。

とするだけで、変数objectは object.on と object.trigger というメソッドを持つようになりました。onはイベントの登録、triggerはイベントの実行です。

なるほど便利、 ちなみに _.extend は underscore.jsの機能で、オブジェクトに異なるオブジェクトのメソッドをもたせることができる、いわゆるサブクラスっぽいことができるメソッド。triggerで引数をわたすこともできるようです。

また、

でディスパッチャの切り分けができます。

object.on(event, callback, [context])Alias: bind

オブジェクトに登録したイベントが発生するたびにコールバック関数が呼び出されます。
オブジェクトに登録したイベントが多すぎるときに分類するときは”hoge:[attribute]”と書くと良いようです。

スペース区切りすると、複数のイベントを登録させることができます。

第三パラメータに値またはオブジェクトを渡すと、それがコールバック関数内で、thisになります。

all という名前のイベントを登録すると、オブジェクトから様々なイベントが実行された後に一緒にallイベントのコールバック関数も実行されるようになります。

このような書き方(イベントマップ)でもイベントを登録することができます。これだと一括でイベントが登録できるので楽。

object.off([event], [callback], [context]) Alias: unbind

オブジェクトから以前登録されたイベントのコールバック関数を削除するメソッドです。
コンテキストが指定されていない場合は、コールバックのすべてのイベントが削除される。
コールバックが指定されていない場合は、イベントのすべてのコールバックが削除。
イベントが指定されていない場合は、すべてのイベントのコールバックは削除。

event→callback→contextと削除される条件と範囲が変わるようです。ということは、同じイベント名でもコールバック関数が違えば、上書きされず2つとも実行される仕様のようですね。下記スクリプトでテストしてみることにします。

2つ出力されたので、2つのコールバック関数が実行されることが確認出ました。イベント名が同じ場合、オーバーライド(上書き)されるのではなく、順々に実行されるようです。

offメソッドの使い方は下記の通り。

onメソッドの使い方サンプルではよくわかりませんでしたが、offメソッドのサンプルを見ることで、backboneのイベントがどこまで柔軟なことができるか目に見えてわかりますね。。null = 全て の範囲はおそらく、backbone.Eventsを使って登録したイベントの範囲なのでしょうから、

によってディスパッチャをわけることで、この全ての範囲をわけることも可能だということにメリットも感じられます。

object.trigger(event, [*args])

eventを実行します。”event event”の書き方であればそれぞれのイベントを実行します。
argsでは,区切りで引数を付けることができます。
ただそれだけ!とてもシンプル!!

object.once(event, callback, [context])

一度実行されたら削除されるイベントです。

イベントといってもコールバック関数が削除されるので、hoge1コールバック関数は消されずに残っています。hoge2だけが実行されません。なるほど便利。

object.listenTo(other, event, callback)

多分、後でlistenToについて説明した項があるんでしょうけど、やっぱり気になるのでここで説明すると、otherは var model = new Backbone.Model(); で作ったモデルに対してeventが発生すると、callbackを実行してくれるというもの。

サンプルだと、モデルに変化があると実行してくれます。 this の中身は o になっているので、モデルに対して o のメソッドが使えるので、 o のメソッドを使ってモデルに対していろんなことができます。なるほど、便利。

眠いけど、どんどんいきます。

object.stopListening([other], [event], [callback])

listenToの逆、イベントの監視をストップします。

object.listenToOnce(other, event, callback)

ちょうどlistenToを同じような振る舞いをしますが、一度監視でコールバック関数が実行されると、監視を終了します。

ずいぶんとやる気のないメソッドですね。

Catalog of Events

モデルやビューやコレクションに対して独自にイベントを定義し利用することは自由だけれど、そのほかにBackbone.jsが独自に追加しているイベントもあるようで、それが下記の通り。

わかるのもありけど、よくわからないのもありますね。ルーティング…?

また、これらイベントは model.set(), collection.add 等のメソッドによって呼ばれるので、 model[“hoge”] = 1 なんてしても呼ばれることはないようです。また、model.set等でモデルにデータを追加した場合に、イベントが呼ばれるのが嫌な場合は、

というよう第三パラメータ、 silent: true を渡すことで、イベントが発生しないようです。

Backbone.Model

ふぅ… いよいよModelへはいります。
Modelというのはデータ構造を表します。というか、データそのものです。身近なものだと、アドレス帳とか、日記とかソシャゲのガチャで集めたカードなどといったデータをまとめてモデルと言います。

Backbone.jsにおけるモデルは、JavaScriptの心臓部です。Backbone.jsはモデルに対して変換や、検証や、プロパティの追加削除機能等 様々な機能を提供します。

以下のサンプルスクリプトは公式にあげられていたものをそのままコピーしたものに日本語コメントを付与したものです。サイドバーの背景色を変更するだけの簡単なスクリプトになっています。公式ページでは再生ボタンを押すことでスクリプトを実行することができます。一度実行すると、ChromeであればWeb Developper Toolsによってモデルの書き換えを行い自由に色を変更することができるので、モデルを変更することでコールバックを実行するといった一連のフローを理解することができます。

ソースコードの動きが読めたでしょうか、通常のコーディングでは、ボタンを押したらここの背景を変えて…みたいな処理を書いていたとおもいますが、このソースコードでは、sidebarモデルのcolorプロパティの値をwhiteに変えただけで、サイドバーの背景色が変わっています。データだけ見ることによって、ロジックまで来にしなくて済むのです。なるほど、便利。

Backbone.Model.extend(properties, [classProperties])

extendによって、Backbone.Modelを拡張し、独自のモデルクラスを生成することができます。
このモデルクラスを利用してモデルを作ると、そのモデルはpropertiesのプロパティを持つようになります。

また、定義済みのメソッドをオーバーライドしたい場合、簡単にオーバーライドできるようにな仕組みは存在ず、めんどくさいけども下記のようなやりかたで実現可能です。

constructor / initializenew Model([attributes], [options])

モデルを生成するときに、デフォルトの値を最初から定義したり、コンストラクタ(モデルを生成するタイミングで呼ばれるメソッド)を定義したりすることができます。

モデルを作成するタイミングでデフォルトの値を最初から定義する場合は、

とします。

モデルを生成するタイミングでメソッドを呼び出したい場合は

このようにします。

model.get(attribute)

モデルから指定されたattributeに定義されてある値を取得します。

model.set(attributes, [options])

モデルに値をセットします。モデルに値をセットすると、changeイベントが発生します。
change:[attribute] というイベントが登録されていた場合は、その[attribute]が変更された場合のみそのイベントに関連付けられたコールバック関数が実行します。

モデルはオブジェクトのように定義することもできます。

model.escape(attribute)

getメソッドと似通ってはいるけど、これはHTMLをエスケープしたものを返すので、XSS対策を行うことができます。(エスケープは、HTMLエンティティ化です)

model.has(attribute)

modelがattributeを持っている場合trueを返します

model.unset(attribute, [options])

modelのattributeで指定されたプロパティを削除します。optionにsilent: true が指定されな限りchangeイベントが呼ばれます。

model.clear([options])

modelからid属性を含む全てのプロパティを削除します。optionsにsilent:true が指定されていない限り、changeイベントが発生します。

model.id

model.idにはユニークな値を指定することができます。特に使い方が今の段階では不明。。

model.idAttribute

model.idとして取得できる別な属性を指定することができます。これは、データベースのテーブルからデータを引っ張ってきたときにカラム名がidではない違う名前だった場合便利です。

なるほど、データベースとのデータの整合性マッチとして model.id は使える。便利。

model.cid

自動的にすべてのモデルに割り当てられた一意の識別子です。
cidは、モデルがまだサーバーに保存されていない場合に便利です。(cidがそのままサーバーに登録するレコードidとして使える)

model.attributes

modelの内包しているオブジェクトがそのまま返ります。

attributesによってモデルデータを直接書き換えたりすることもできます。モデルデータをコピーしたい場合は

を使用します。

ただ、モデルデータを直接書き換える場合、プロパティ名にキーを含ませることが可能になってしまうので、それをやってしまうと、”イベントをスペースで区切る”

model.changed

最後に変更された属性がオブジェクト(ハッシュ)で返ります。変更差分のみを保存させるロジックを書くのに便利です。

model.defaults or model.defaults()

デフォルト値の取得および設定ができます。

デフォルト値は、モデルクラスの参照によって渡されるので、書き換えには注意が必要です。

model.toJSON()

モデルをJSON文字列に変換するためのオブジェクトを返します。このメソッドは、一見JSON文字列を返してくれるように見えますが、JSON.stringifyによって変換するためのオブジェクトが用意されるだけのものです。また、JSON.stringifyを使用する場合、toJSONが暗黙的に呼び出されるようです。(省略できます)

model.sync(method, collection, [options])

サーバーへモデルの状態を保持する Backbone.syncを使用するためのオプションです。

model.fetch([options])

Backbone.syncを利用することで、モデルの状態を再設定します。
現在のモデルデータをサーバーから取得したモデルデータと比較して、差異が合った場合やローカル側のモデルデータが空になっている場合はchangeイベントが発生します。

model.save([attributes], [options])

Backbone.syncによってモデルデータを保存します。検証に成功した場合、jqueryXHRを返します。
変更したいプロパティのみを記述し、記述されないプロパティはサーバー上から変更されません。
save時には、modelのvalidateメソッドによってデータの検証が行われるので、検証に失敗した場合は保存されません。

モデルがすでにサーバー上にある場合、HTTPメソッドはPUTとなり、ない場合は、POSTとなります。

saveが実行されると、 モデルイベントが、 change、request、syncの順番で発生します。
基本的に、saveは非同期で行われますが、サーバーの処理を待ちたい場合は、optionsに wait: true を指定します。

model.destroy([options])

Backbone.syncによって、HTTPメソッドのDELETEによってモデルをサーバー上のデータベーステーブルから削除してもらうよう命令することができます。

モデルにid属性がない場合は、destroyは失敗しfalseが返ります。

Underscore Methods (6)

Underscoreの基本的なメソッドをモデルに対して使用することができます。_を使わなくても、モデルのメソッドとしてデリゲート(委任)されているのでそのままモデルに対して使用できます。

model.validate(attributes, options)

モデルの検証を定義するためのメソッドです。検証ロジックはデフォルトでは未定義(特に何もしない)担っています。
モデルデータによってJavaScriptの任意のコードが実行できるようなものやバックエンドに何らかの影響を及ぼすようなものに対してvalidateの定義が推奨されています。

検証は、saveメソッドを使用する際に呼び出されますが、 model の options に {validate:true} を指定することで、saveする前に呼び出すことができます。また、検証に失敗するとデータベースに変更は保存しません。

検証に失敗したモデルに対して invalid イベントが発生されます。

model.validationError

検証に最後に失敗した際のエラー情報が返ります。

model.isValid

検証を直接実行します。

model.url()

モデルに紐付けられるURLを返します。(サーバー上のリソース)
urlRoot属性がモデルクラスにない場合このメソッドは失敗します。

model.urlRoot or model.urlRoot()

モデルをHTTP経由のリソースの場合対応するURLが必要になってきます。その際に便利なのが。urlRootです。urlRootを定義することでモデルからURLを取得することができるようになります。また、このurlRootはコレクションに対しても有効です。

model.parse(response, options)

parseはデフォルトではresponseをそのまま戻り値として返すだけのメソッドです。extendで処理をオーバーライドして使用します。fetchやsaveを実行する際に、取得する前のデータをちょっと加工したりするのに使います。

また、モデル作成時のデフォルトのデータ指定時に、オプションに { parse: true } を指定すると、内部でparseが呼び出されデータを加工してからモデルにデータが追加されます。

model.clone()

モデルのディープコピーを行います。モデルは完全に別々のものとして扱われます。

model.isNew()

サーバー上に保存されておらず、新しく作られたモデルである場合 true を返します。

model.hasChanged([attribute])

モデルのプロパティである [attribute] に変更があった場合、 true を返します。

model.changedAttributes([attributes])

modelの変更点を返します。[attributes]にハッシュを指定すると、そのハッシュが返ります。

model.previous(attribute)

プロパティの値が変更される前の値を取得します。

model.previousAttributes()

モデルの変更前の全ての属性を返します。
前の状態に戻るとき(ロールバック)に便利です。

Backbone.Collection

やっとモデルが終わりました。覚えること多くて大変です。次に、コレクションを眺めていきます。
コレクションは、名前の通りコレクションで、何をコレクションするかというとモデル。複数のモデルを一つにまとめたものをコレクションと言うらしい。コレクションにも、モデルと同じようにイベントを登録したりすることが可能で、イベントの扱いがもっと簡単になるような概念です。

例えば、今まで人モデルにイベントを登録するには、一人一人にイベントを登録しなければいけませんでしたが、一人一人を一つのコレクションにまとめることによって、一括したイベント管理が行えるようになるということらしい。

Backbone.Collection.extend(properties, [classProperties])

モデルクラス同様、コレクションも独自のコレクションクラスを生成することができます。

collection.model

コレクションクラスには、モデルクラスを含めることが可能で、それを実現するにはcollection.modelをオーバーライドします。

また、modelを関数としてオーバライドすると、関数でモデルを生成することもできます。

constructor / initialize new Collection([models], [options])

Collectionのconstructorによる初期化では、モデルを渡すことができます。

collection.models

Collection内部への直接直接アクセスを行います。本来であればgetを使用するべきです。

collection.toJSON()

これもモデルと同じように、JSON文字列にシリアライズ可能なハッシュを返します。
一見toJSONだけで文字列にできるように見えますができません。JSON.stringifyする際に暗黙的に呼ばれるので、あえて明示的に使用する必要はありません。

collection.sync(method, collection, [options])

サーバーへモデルの状態を保持する Backbone.syncを使用するためのオプションです。

Underscore Methods (28)

Underscoreの基本的なメソッドをコレクションに対して使用することができます。_を使わなくても、コレクションのメソッドとしてデリゲート(委任)されているのでそのままコレクションに対して使用できます。

collection.add(models, [options])

コレクションにモデルを追加します。modelsにはそのままインスタンスとして生成済みのモデルを渡すこともできますが、ハッシュをそのまま渡すことで、内部でモデルを生成して追加させることもできます。モデルを追加するとcollectionには add イベントが発生します。

collection.remove(models, [options])

指定したモデルをコレクションから削除します。
モデル削除時には、 remove イベントが collection に対して発生します。

collection.reset([models], [options])

コレクションをハッシュを元に作り直します。実質的にリセットです。

collection.set(models, [options])

新しいコレクションのハッシュをセットします。オプションにdelete: falseを指定すると、既存のモデルは削除されることはありません。merge:false merge:true add:false 等もあるようです。

collection.get(id)

コレクションからidまたはcidで指定されたモデルを取得します。

collection.at(index)

コレクションで、indexから指定されたモデルを取得します。

collection.push(model, [options])

コレクションの最後にモデルを追加します。

collection.pop([options])

コレクションの最後からモデルを取り出して、コレクションから削除します。

collection.unshift(model, [options])

コレクションの先頭にモデルを追加します。戻り値に追加したモデルが返ります。

collection.shift([options])

コレクションの先頭からモデルを取り出して、削除します。

collection.slice(begin, end)

begin番目からend番目までのモデルを切り出したものを返します。(コレクションから削除されるわけではありません)

collection.length

コレクションの保有しているモデルの数を返します。

collection.comparator

コンパレータはデフォルトでは定義されていません。このコンパレータをオーバーライドし、コンパレータとして使用するキーを設定すると、そのキーによって自動的にモデルをソートしてくれるようになります。

collection.sort([options])

明示的にこれを呼び出す必要はありません。ソート機能を使いたい場合、コンパレータによる自動ソートの使用をおすすめします。もし自動ソートをやめたい場合は、オプションに、{sort: false}を指定します。

collection.pluck(attribute)

collection.where(attributes)

渡された{key:value}を持つモデルを複数返します。

collection.findWhere(attributes)

渡された{key:value}を持つモデルで一番最初に見つかったモデルのみを返します。

collection.url or collection.url()

サーバー上のコレクションに結びつく独自のURLを設定します。

collection.parse(response, options)

fetchでサーバーからのレスポンスを得る際に、得たデータをコレクションとして取り入れる前に、少し加工してからモデルに取り入れるための処理を行います。

urlを使用する場合はこのようにします。

何も削除せずに、追加と更新のみを行う処理をしたい場合はこのようにします。

また、ページネーションを表すのに

が使用できるそうですが、どう使えばいいのか不明。。

collection.create(attributes, [options])

新しくモデルを作成すると同時に、データベース上にも新しく作成したモデルデータを登録します。
なるほど便利。

Backbone.Router

長い…長すぎる。上から下へ眺めるだけなのに何時間だったのだろうか。サンプルスクリプトをちまちま書いてたからか、今一番見たくないのはスクロールバー。

それはさておき、いよいよルーティングです。ブラウザのページを動的に切り替えるためのロジックなのでかなり期待大!です。

本題へ移ります。
ルーティングというのはブラウザのページ切り替えのURLのことです。ページを切り替えるとURLが代わり、URLひとつひとつに割り当てられているページが違う。当たり前のことではありますが、このURLはこれ、このURLはこっちと、振り分けていくことをルーティングと言います。

これまでのWebサービスは、ページを切り替える度に画面がフラッシュし、DNS解決やHTTPリクエストを送ったりとページ切り替えに少なからずストレスを感じずにはいられませんでした。Twitterがhashchangeによって動的なページ切り替えを実現はしましたが、URLが「https://hogehoge.com/#!hoge」というようにhash=#を使わなければならず、URLとしては少し見栄えが悪いものでした。

そこで、History API というものが登場し、HTTPリクエストを発生させなくても、URLを書き換えられるようになりました。URLを書き換えられるということは、URLを書き換えるタイミングで、HTMLもJavaScriptを使って書き換えるようにすれば、クライアントにとってあたかもページが高速に切り替わった印象を与えることができるようになります。

それに、ajaxの技術を組み合わせることで、リッチなWebアプリケーションの開発を行うことができます。そんなことを実現させてくれるのが、Backbone.Routerです。

Backbone.Routerを使用するには、 ページのロードが完了したら
Backbone.history.start();
または
Backbone.history.start({pushState: true});
によって、ルーティング初期URLとするために呼び出してください。

Backbone.Router.extend(properties, [classProperties])

特定のURLフラグメントが一致したときに実行されるアクションを定義した
ルーティングクラスを作成します。
先頭に / は必要ありません。

router.routes

このハッシュオブジェクトによってルーティングを行います。
:param の部分がパラメータになり、 *splat の部分が /hoge/hoge/hoge/ と構造を表すことができます。
ルーティング時、あってもなくても良いような指定を行う場合は (/:optional) と書きます。

例えば
“search/:query/p:page”

search/obama/p2
にアクセスすることができ、:query にはobama、 :page には 2が入ります。

“file/*path”

file/nested/folder/file.txt
としてアクセスできます。

具体的には、ルーティングは

のように書くことができ、

としてアクションを登録することもできます。

new Router([options])

オプションにハッシュを渡すことで初期化メソッドを実行することができます。

router.route(route, name, [callback])

手動でルーティングのルートを作成します。 router.routes による定義やアクションメソッドの定義はできません。

router.navigate(fragment, [options])

URLの変更とアクションの実行を行い、ページ遷移の挙動を振る舞います。

Backbone.history

hashchange または pushState によるコールバック関数としての機能を果たします。
Hisory APIに対応していないブラウザの場合はhashchangeによるページ遷移を行います。

Backbone.history.start([options])

ルーティングが正しく設定してある場合において、 hashchangeイベントを監視するようにするには、
Backbone.history.start()
を実行します。

HTML5のpushStateを利用したい場合は、
Backbone.history.start({pushState: true});
を指定します。

ルートURLを指定するには、
Backbone.history.start({pushState: true, root: “/public/search/”})
とします。

Backbone.history.start() は 定義されたルートURLが一致するとtrueを返し、一致しない場合はfalseを返します。

hashchangeの場合、iframeに依存しているので、DOMの生成が完了しおわってから実行するようにしてください。

Backbone.sync

Backbone.syncがサーバーからデータを読み込んだり、保存したりする関数です。デフォルトでは、RESTfulなJQueryなAjaxが呼び出されるようになっていますが、この関数をオーバーライドすることによって、WebSocketだったり、localStorageだったりと、データストアを自由に切り替えることができます。

オーバーライドするには、

とすることで、自由に処理を設定できます。console.logにて、どのようなmethodやmodelが呼ばれているのかを確認することができます。modelには model.urlが割り当てられていることがあるので、model.urlからURLを取得し、そのURLに対して通信を行うこともできます。

  • method – the CRUD method (“create”, “read”, “update”, or “delete”)
  • model – the model to be saved (or collection to be read)
  • options – success and error callbacks, and all other jQuery request options

また、 モデルやコレクションがサーバーに通信を行うとき、 それぞれに対して、 request イベントが発生します。

RESTfulな実装の場合、各種HTTPメソッドはこのような割り当てになっています。

    create → POST /collection
    read → GET /collection[/id]
    update → PUT /collection/id
    delete → DELETE /collection/id

Backbone.ajax = function(request) { … };

ajaxをカスタマイズします。

Backbone.emulateHTTP = true

REST/HTTPをサポートしていない従来のWebサーバーを利用している場合、 Backbone.emulateHTTP を trueにすると、 X-HTTP-Method-Override header を付与し、 HTTPメソッドは _method に割り当てられます。

Backbone.emulateJSON = true

Backbone.emulateJSON を trueにすると、
JSONとしてエンコードのリクエストを扱うことができない従来のWebサーバで application/x-www-form-urlencoded として取得するようになります。

Backbone.View

モデルに登録したイベントのchangeイベントを監視して、モデルに変更があるタイミングでテンプレートエンジンを利用して画面を再描画します。

Backbone.View.extend(properties, [classProperties])

カスタムビュークラスの作成を開始します。

eventsには、

  • tagName
  • id
  • className
  • el
  • event

が定義できます。

constructor / initialize

ビューインスタンスの生成を行います。

view.el

ここに生成済みのdomが格納されます。

view.$el

DOM要素がjQueryでラッピングされたものです。

view.setElement(element)

別のDOM要素にViewを適用したい場合に使用します。

view.attributes

view.elの属性のハッシュオブジェクトらしいが、undefinedしか帰ってこないため不明。

view.$(selector)

view.$で jQueryを利用することができます。

view.render()

デフォルトでは何もしませんが、this.elによって生成されたHTMLとテンプレートとモデルデータをレンダリングするようにこの関数をオーバーライドします。
レンダリング終了時にこの関数を呼び出すと良いです。

ここではアンダースコアのテンプレートエンジンを使用していますが、 Mustache.js や Haml-js など様々なテンプレートエンジンがあるので、使ってみることをおすすめします。

view.remove()

ビューとビューの監視イベントを削除します。

delegateEvents([events])

undelegateEvents

ビューに委任されている全てのイベントを削除します。

サンプルスクリプト

よくわからなかったのでサンプルスクリプトを書いてみました。

モデルの変更によって動的にビューが書き換わっているはずなのに、イベントが死なない…
すごい…
また、サンプル中では、テンプレートを一つしか使ってないので、これをうまくいろんなテンプレートを使えるようにオブザーバを工夫する必要があります。

Utility

var backbone = Backbone.noConflict();

既存のbackboneオブジェクトを破壊せずに、もう一つbackboneを作成して使用します。

Backbone.$ = $;

jQueryのエイリアスです。

最後に

ようやく下まで眺め終わりました。眺めるレベルじゃない気もしますが、とりあえず….眠いです。おやすみなさい。

テストとjQueryのeachっぽい何かを書いてみた

jQueryは便利だけど、わざわざjQueryをロードせずともできるだけ同じようなことがしたいというときに便利。jQueryほどセレクタの指定ができないが、forEachでぐるぐると実行してくれるので便利。おまけにテストも書いてみました。

使う場面としたら、Chrome拡張やブックマークレットくらいでしょうか。

こんなかんじでブックマークレットも作れる