イベントの一覧 原文

Backbone.jsで発火する組み込みイベントの一覧を示します。このほかにも、ModelやViewで独自のイベントを自由にトリガすることができます。

※訳注:以下のリストの括弧はイベントリスナに与えられる引数です。ModelとCollectionが絡むイベントは、Model -> Collectionの順に、双方でイベントが発火します。

なぜ他のフレームワークでなく、Backboneを使うのか? 原文

もしあなたが上に示したexamplesリストを見て、適合するシーンをまだ掴み切れていないのであれば、より具体的に述べることができます。Backbone.jsは細心の注意を払いながら、より良い実装のために確実で判断したほうがよいことに勝手な答えを出さず、野心的なインターフェースを備えたデータリッチなWebアプリケーションが必要とする共通基盤を提供することを目的としています。

複数の手段があります 原文

一般的にこれから始める人々にとって、このページに記載されている例は、ある種、唯一の真実のように映ります。実際には、Backbone.jsはクライアントサイドコードにおける多くの共通パターンに、大部分で依存していません。例えば…

ModelとViewをつなぐ参照は、複数の方法で制御できます。一部の人は、ポインタを直接持たせてViewとModelを1:1にすることを好みます(model.viewview.model)。他にも、Controllerを設けて、Viewを階層的に作成・編成して、コントロールする方法も好まれます。その他はイベントアプローチを好み、直接メソッドを呼ぶかわりに、常にイベントを発火させてコントロールします。これらのスタイルのすべてがうまく動作します。

バッチ操作はモデルにおいて一般的ですが、多くの場合はサーバーサイドの設計によって異なった制御を行うほうが理想的です。一部の人々はAjaxリクエストを個々に記述することを惜しみません。あるいは、/notes/batch/destroy?ids=1,2,3,4 のようなRESTfulなバッチ操作のための明示的なリソースを作成します。他にも、JSONをトンネルにすることでRESTを実現し、次のようなチェンジセットとしてリクエストを作成することもあります。

{
  "create":  [array of models to create],
  "update":  [array of models to update],
  "destroy": [array of model ids to destroy]
}

自由に独自イベントを定義できますBackbone.Eventsは、あらゆるobjectやprototypeと混ぜ合わせて使えるようにデザインされています。独自のカスタムイベントをbindまたはtriggerするのに、model.on("selected:true")model.on("editing")のように任意の文字列をイベント名として使用できます。

UIの描画はあなたが望むように行われます。Backboneはrender関数の中で、Underscore templatesMustache.js、直接的なDOM操作、サーバーサイドで作ったHTMLスニペット、jQuery UIなどのいずれが使用されることを問いません。時にはModelごとのViewを作成するでしょうし、時にはタイトなループの中で多数のModelを一度に描画するViewを作成することもあるでしょう。同じアプリの中であっても、関係するデータの量や、UIの複雑さに応じてどちらの方法でも適切になりえます。

ネストしたModelとCollection 原文

たとえば、多くのMessage modelをもつMailbox modelを考えてみましょう。これを処理するための良い方法のひとつは、Mailboxにthis.messages collectionを持たせMailboxがはじめに開かれたときに、遅延ロードされるようにします。おそらくMessageList viewは、addremoveイベントをリスニングするようになるでしょう。

var Mailbox = Backbone.Model.extend({

  initialize: function() {
    this.messages = new Messages;
    this.messages.url = '/mailbox/' + this.id + '/messages';
    this.messages.on("reset", this.updateCounts);
  },

  ...

});

var Inbox = new Mailbox;

// And then, when the Inbox is opened:

Inbox.messages.fetch();

もしあなたが他のもっと厳格な何かを探すのであれば、モデル間の洗練されたアソシエーションを追加したBackboneプラグインがいくつかあり、Wikiで見つけることができます

BackboneはネストしたModelやCollectionまたは”has many”なアソシエーションの直接的なサポートを含みません。なぜならばクライアントサイドで構造化データをモデリングするための良いパターンが幾つかあり、Backboneはそれらのいずれかを実装するための基板を提供する必要があります。あなたが望むように…

初期モデルの読み込み 原文

あなたのアプリが最初に読み込まれたとき、そのページをレンダリングするのに必要になるであろう初期データをセットしておくのが一般的です。そこでAjaxリクエストを余分に行ってfetchするよりも、代わりになる良いパターンは、ページにそれらのデータを埋め込んでおくことです。そして、resetすることで、Collectionの初期データを入れることができます。DocumentCloudでは、ワークスペースにはERBテンプレートを使っていて、このように何かしらを行います。

<script>
  var Accounts = new Backbone.Collection;
  Accounts.reset(<%= @accounts.to_json %>);
  var Projects = new Backbone.Collection;
  Projects.reset(<%= @projects.to_json(:collaborators => true) %>);
</script>

あなたは、JavaScriptインジェクション攻撃を防ぐために、JSON文字列内で</escapeする必要があります。

Backboneの拡張 原文

多くのJavaScriptライブラリは、自身を独立性の高い状態に封じこめた上で、ユーザーがそれらの公開されたAPIを呼び合うことで相互に作用することを意図していますが、Backboneはそのような種類のライブラリではありません。

なぜならば、Backboneはアプリケーションの基礎を提供していて、ユーザーにとって適当な方法で、自由に継承し機能を拡張することを意図しています。ソースコード全体で、このような拡張を容易にするための注釈がつけられています。

コア機能を担っている部分は非常に少ないということが分かり、またそれらのほとんどは、必要性に応じてオーバーライドないし、拡張することができます。

Backbone.Model.prototypeにメソッドを追加したり、ベースとなる独自のサブクラスを作成しても心配することはありません。それこそが想定された方法なのです。

Backboneはどのように伝統的なMVCと関係しているか 原文

異なるModel-View-Controllerパターンの実装において、コントローラーの定義について異議を唱える傾向にあります。何かの役に立つのであれば、BackboneはViewクラスをControllerのようなものとして考えることができ、UIから発生するイベントをディスパッチしながら、従来のViewのようにHTMLテンプレートも使用します。我々がそれをViewと呼ぶのは、それがUIロジックの単位を示し、単一のDOM要素の内容に責任を持っているからです。

Backboneの全体的な構造を、RailsのようなサーバーサイドMVCフレームワークと比較すると、このようなラインアップになります。

thisを束縛する 原文

恐らく、最も一般的なJavaScriptの落とし穴は、コールバックとしてfunctionを渡したときにthisが失われることでしょう。Backboneでeventsとコールバックを扱うときにはしばしば、Underscore.jsの.bind](http://documentcloud.github.com/underscore/#bind)と[.bindAllの有用さを見いだすでしょう。 Backboneのevetnsにコールバックをバインドするとき、オプションの第三引数にthisを指定することで、あとでコールバックが呼び出されたときにそれを使うようにできます。

var MessageList = Backbone.View.extend({
  initialize: function() {
    var messages = this.collection;
    messages.on("reset", this.render, this);
    messages.on("add", this.addMessage, this);
    messages.on("remove", this.removeMessage, this);
  }

});

// Later, in the app...

Inbox.messages.add(newMessage);

Railsと一緒に使う 原文

Backbone.jsは元々Railsアプリケーションから抽出されていて、サーバーサイド(Rails)のModelへの副作用なしにクライアントサイド(Backbone)のModelが同期できるようになっていますが、それでも注意すべき点がいくつか残っています。

デフォルトでは、RailsはModelをJSONで表すときに、Model名をJSONのrootに余分に含ませてラップします。これをデフォルトでラップを含ませないように設定できます。

ActiveRecord::Base.include_root_in_json = false

のように設定します。それ以外の場合は、parseをオーバーライドして、Model名のラッパーを取り除いてModelの値を取り出してやります。同様に、BackboneのPUTとPOSTにおいてModelをJSONで表現するときも、RailsはデフォルトでModel名がrootに含まれることを期待します。Controllerでparamsから直接的に値をフィルタすることができ、もしくはBackboneのtoJSONを上書きしてRailsが期待するようになるようrootにModel名を追加します。