HOME > Learning Place >  No.9 データモデル

データモデル

今回は、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 フレームワークのクラスシステムについて詳しく解説します。お楽しみに。

Learning Placeトップに戻る

PAGETOP