必要条件

この記事に必要な予備知識

  • サンプルファイル:

ユーザーレベル

すべて

原文 作成日: 2012/3/19

Backbone.js Wine Cellar tutorial – Part 2: CRUD

第1部:はじめに」では、ワインセラーアプリケーションの基本構造を構築しました。第1部で作成したアプリケーションは読み取り専用であるため、ワインリストの表示と、選択したワインの情報の表示しか行えません。

第2部では、ワインをリストに登録、更新、削除(CRUD = create, update, and delete)できる機能を追加します。

HTTPメソッド

URL

アクション

GET

/api/wines

すべてのワインを取得します

GET

/api/wines/10

id == 10のワインを取得します

POST

/api/wines

ワインを新規登録します

PUT

/api/wines/10

id == 10のワインの情報を更新します

DELETE

/api/wines/10

id == 10のワインを削除します

ダウンロードには、これらのサービスのPHP版(Slimフレームワークを使用)が含まれています。こちらの投稿では、同様の内容でJavaバージョンのAPI(JAX-RSを使用)を使用しています。

RESTful以外のサービスでBackbone.jsを使用する

RESTfulサービスで永続化レイヤーを利用できない場合は、Backbone.syncを無効にできます。以下に、Backbone.jsドキュメントの記述を引用します。

Backbone.syncは、modelをサーバーから読み込んだり、サーバーに保存しようとするたびにBackboneに呼び出される関数です。デフォルトでは、Backbone.syncは(jQuery/Zepto).ajaxを使用してRESTful JSONリクエストを作成します。WebSocket、XML transport、またはLocal Storageなど別の手段で永続化を行う場合は、Backbone.syncを無効にできます。

このチュートリアルでは、RESTful以外のサービスについては説明しません。詳しくは、Backbone.jsのドキュメントを参照してください。

新規登録、更新、削除機能の追加

このチュートリアルでは、このアプリケーションを開発します。このアプリケーションのオンライン版では、ワインの新規登録、更新、削除などの機能は無効になっています。

第2部では以下のコードを使用します。主な変更点については、コードの後で説明します。

コードの説明:

Wine(2~14行目)

第2部では、Wine Modelに次の2つの属性を追加します。

  • urlRoot(3行目):Modelデータを取得または永続化するRESTfulサービスのエンドポイント。この属性は、Collectionに含まれないModelの取得または永続化を行う場合のみに必要とされます。ModelがCollectionに含まれている場合は、Collection内に定義されたurl属性さえあれば、Backbone.jsはRESTful APIを使用してデータを取得、更新、削除する方法を理解します。
  • Defaults(4行目):モデルの新しいインスタンスを作成するときに使用されるデフォルトの値。この属性はオプションです。ただし、このアプリケーションでは、wine-detailsテンプレートに「空の」ワインモデルオブジェクトを表示する必要がありました(ワインを新規登録する場合)。

WineListView(22行目から40行目)

ユーザーがワインを新規登録すると、自動的にワインリストに表示されるようにすることができます。それには、ViewをWineListViewモデル(ワインのコレクション)のaddイベントにバインドします。addイベントが発行されると、アプリケーションがWineListItemViewのインスタンスを新しく作成し、リストに追加します。

WineListItemView(42行目~62行目)

  • ユーザーがワインの情報を変更したときに、対応するWineListItemViewを自動更新し、変更内容を反映させるようにすることができます。それには、Viewをモデルのchangeイベントにバインドし、イベントの発行時にrender()関数を実行します。同様に、ユーザーがワインを削除したときに、ワインリストからも自動的に削除されるようにすることができます。
  • それには、Viewをモデルのdestroyイベントにバインドし、イベントの発行時にカスタムのclose関数を実行します。

    重要:メモリリークを避け、イベントが複数回発行されないようにするには、DOMからリストの項目を削除する前に、イベントリスナーのバインドを解消する必要があります。
  • いずれの場合も、リスト全体を更新する負荷がなくなります。変更の影響を受けたリスト項目のみが更新または削除されるだけです。

WineView(64行目~123行目)

カプセル化の観点に立って、「Save」ボタンと「Delete」ボタンのイベントハンドラーはWineView内で定義されます。これは、「クラス」定義を使用せず、結束性の弱いコードブロックとして定義するのとは対照的です。Backbone.jsのEventsシンタックスを使用すると、バックグラウンドでjQueryデリゲートメカニズムが使用されます。

ユーザーがフォームに入力を行ったときにモデルを更新させるには、いくつかの方法があります。

  • 「リアルタイム」アプローチ:フォームで変更が行われたときに変更ハンドラーを使用してモデルを更新します。これは、実は双方向のデータバインディングです。モデルとUIのコントロールが常に同期しています。このアプローチでは、リアルタイムにサーバーに変更を送信するか(暗黙的な保存)、またはユーザーが「Save」ボタンをクリックするまで待つか(明示的な保存)を選択できます。前者の方法は、フィールド間の検証ルールがあると、メッセージが頻繁に表示されることになり、実用的とは言えません。後者の方法では、「Save」をクリックせずにユーザーが別の項目に移動しようとした場合に、モデルの変更を元に戻すように要求されます。
  • 「遅延」アプローチ:ユーザーが「Save」をクリックするのを待って、UIコントロール内の新しい値に基づいてモデルを更新し、変更をサーバーに送信します。

この説明は、Backbone.jsのみに該当する記述ではないため、この投稿の主旨からは外れます。簡単にするために、ここでは遅延アプローチを使用しました。ただし、引き続きchangeイベントを送信し、コンソールに変更をログするために使用します。このようにすると、アプリケーションのデバッグ時、特にバインディングを解消したことを確認したい場合に便利です(「close関数」を参照)。changeイベントが複数回発行された場合は、バインディングがきちんと解消されていない可能性が高いと思われます。

HeaderView(125行目~148行目)

Backbone.jsのViewは、WineListView、WineListItemViewおよびWine Viewなどのように、通常はドメインモデルを表示するために使用しますが、コンポジットUIコンポーネントを作成するときにも使用できます。例えば、このアプリケーションでは、様々なコンポーネントで構成され、独自のロジックを格納しているHeader View(ツールバー)の定義に使用しています。

次のステップ

第1部と第2部ではアプリケーションはディープリンクをサポートしていませんでした。例えば、リストからワインを選択したり、アドレスバーのURLをコピーして、他のブラウザーウィンドウに貼り付ける機能は実装されていないため、これらの操作を行うことができません。「第3部:ディープリンクとアプリケーションの状態」では、ディープリンクが完全に実装されるようにします。