データモデル
今回は、Sencha フレームワークの裏側を支える、データモデルにスポットを当てることにしましょう。 Sencha フレームワークでは、データを取り扱うための便利なクラスが多数用意されています。 それらのクラスによって次のことができます。
- サーバーなど外部からデータを取得して、それをキャッシュする
- そのデータをコンポーネントにバインドして表示を更新する
- 修正されたデータを外部のデータソースとシンクロする
Sencha のデータモデルがあるおかげで、Sencha のビュー側のアプリケーションでは、データソースについて意識しなくても済みます。 そのデータがどこからやってきて、最終的にどこを更新するべきか、といったことを知らないままで、システムを作っていくことができます。 それらのややこしいことは、すべてデータモデルが担ってくれるのです。 そのおかげで、データの保存先が変わった場合でも、そのデータを画面に表示しているビューなどを変更する必要はなく、データモデルの一部を変更するだけで、そのデータソースに対応できます。
データモデルを構成するもの
データモデルを構成する役者さんには、次の方たちがいます。
- Model – データの形式の定義。そのインスタンスは1件のレコード
- Store – Modelのインスタンスのコレクション。DBでいうとテーブル
- Proxy – データをどこから、どんな方法で取得するかを知っている
- Reader / Writer – データの保存される形式を知っている
その前に通信について考える
ところで、Sencha フレームワークにおいては、サーバーサイドとどのように通信するのでしょうか。 通信をするための重要なクラスが2つあります。
- Ext.data.Connection
- Ext.data.JsonP
Ext.data.Connection
Ext.data.Connection クラスは、Ajax 通信処理を行うクラスです。 実際には、このクラスのシングルトンインスタンスである、Ext.Ajax クラスを使います。
XmlHttpRequest (XHR) をラッピングしてクロスブラウザー化しています。 Ext.Ajax.request() メソッドを使うと、手軽に Ajax 通信をすることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 | Ext.Ajax.request({ url: 'page.php', params: { id: 1 }, success: function(response){ var text = response.responseText; // 成功したときの処理 } failure: function(response){ // 失敗した時の処理 } }); |
メソッドの引数には、urlやparamsなどのパラメーターをセットしたオブジェクトを渡します。
リクエストは非同期で行われ、そのレスポンスを success と failure のいずれかのコールバック関数で処理します。
Ext.data.JsonP
Ajaxリクエストには、同一ドメイン制約があります。 ですから、ページのあるドメインからしかデータを取得することはできません。
でも、他のドメインからデータを取得したい事がありますね。 他のドメインからデータを取得する方法としては、JSONPという方法があります。 JSONPについて詳しくは、 Wikipedia の記事 などを参照していただくことにしますが、これのクライアント側を一から書くのはちょっと面倒なんです。
Sencha フレームワークでは、JSONPの通信をするためのクラスも用意されています。 それが、Ext.data.JsonP クラスです。
Proxyクラス
Sencha フレームワークではこれらのクラスを使って、サーバーからデータを取得しますが、 データモデルの中では、このクラスを直接使うのではなく、Proxy (Ext.data.Proxy) を使います。 Proxy クラスは各種データソースとのやり取り(CRUD)を行う機能を提供します。 Proxy というのは、データの格納場所との通信方法を知っているクラスで、 通常は直接利用することはなく、Store または Model の proxy コンフィグで設定します。 通信する相手によって、Proxy クラスのサブクラスを使います。
Proxy クラスには大きく分けて、Server Proxy (Ext.data.proxy.Server) と Client Proxy (Ext.data.proxy.Client) があります。
Server Proxy
サーバーとデータをやりとりします。 この Server Proxy の中では、前記の Ext.data.Connection や Ext.data.JsonP をクラスを使って通信をしているのですが、Proxy をデータモデルに設定する事により、通信を強く意識することなく使えるようになっています。 サーバーとの通信方法によって、次の Proxy が用意されています。
- Ajax Proxy (Ext.data.proxy.Ajax) :
同一ドメイン内のサーバーとデータのやり取り行います。 - Rest Proxy (Ext.data.proxy.Rest) :
同じく同一ドメイン内のサーバーとの通信に使いますが、RESTful な通信をします。 - JSONP Proxy (Ext.data.proxy.JsonP) :
JSONPを使ったクロスドメインのサーバーとデータのやり取り行います。 - Direct Proxy (Ext.data.proxy.Direct) :
Ext.Direct という Sencha フレームワークが提供するRPC (Remote Procedure Call) を利用した Proxy です
Client Proxy
こちらはサーバーと通信するのではなく、クライアントでデータを保持します。
- Memory Proxy (Ext.data.proxy.Memory) :
ブラウザーのメモリ上にデータを格納・読み込みを行います。。 - LocalStrage Proxy (Ext.data.proxy.Local):
ブラウザーのローカルストレージにデータを保存します。 - SessionStrage Proxy (Ext.data.proxy.Local/Session):
ブラウザーのセッションストレージにデータを保存します。
Memory Proxy のデータはJavaScriptの変数内にデータを保持しますので、リロードされたらデータは失われます。
Reader/Writerクラス
Proxy はデータソースを知っていて、それらからデータをやりとりしますが、 Proxy がやりとりするデータの形式によって処理をするのが、Reader (Ext.data.Reader) と Writer (Ext.data.Writer) です。 Proxyクラスに reader / writer というコンフィグを設定することで、各種フォーマットのデータの読み込み・書き込みを行います。
Reader は Proxy を介して取得したデータを読み込み、解析し、Ext.data.Model オブジェクトの配列を生成します。 扱うデータ形式によって次のようなサブクラスがあります。
- Ext.data.reader.Array
- Ext.data.reader.Json
- Ext.data.reader.Xml
Writer は Readerとは逆に Ext.data.Model を Proxy を経由してデータソースに書き込みます。 Writer が必要なのは Server 側のデータソースだけであり、Client側のデータソースに対してはWriterは必要ありません。
- Ext.data.writer.Json
- Ext.data.writer.Xml
Modelクラス
Sencha フレームワークのアプリケーションで利用するデータを格納するためのオブジェクトは通常 Model クラス (Ext.data.Model) を継承して作成します。 Model では、fields コンフィグで、データ構造を定義します。 Model 内部のデータは、前述のように Model または Store に直接設定された Proxy を介してデータソースから読み込まれたり、書き込まれたりします。
次のコードは Ajax Proxy をセットした Model の定義例です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Ext.define('User', { extend: 'Ext.data.Model', fields: [ {name: 'name', type: 'string'}, {name: 'age', type: 'int', convert: null}, {name: 'phone', type: 'string'}, {name: 'alive', type: 'boolean', defaultValue: true, convert: null} ], proxy: { type: 'ajax', url: '/users.json', reader: { type: 'json', root: 'users' } } }); |
Storeクラス
Model に格納されるデータは、通常は複数個存在しますので、それらはまとめて Store (Ext.data.Store) に格納します。 いわば、クライアントサイド(ブラウザー側)の「データ保管庫」です。
単なる Model の配列ではなく、Model をフィルタリングしたり、ソートしたり、条件によって Medel をサーチしたり、といった機能が備わっています。
データを表示する各種UI部品 (Ext.grid.Panelなど) に Store をバインドすると、そのデータを表示できます。
先ほどの、Userモデルの集合を扱うストアを次のように定義します。
1 2 3 4 | var myStore = Ext.create('Ext.data.Store', { model: 'User', autoLoad: true }); |
Sencha フレームワークで重要な部分を担うデータモデルについて解説しました。 次回は、 クラスシステムの理解 と題して、Sencha フレームワークのクラスシステムについて詳しく解説します。お楽しみに。