Ext.dataのProxy, Reader, Storeについて
GridPanel、ComboBox、DataViewなどのコンポーネントから利用されるProxy、Reader、Storeの各クラスですが、生成方法が色々あって分かりづらかったのでまとめてみました。
まず、StoreはView(Grid)からのリクエストに応じて内部の情報を操作するクラスで、基本的に下記のような構造で生成します。
var store = new Ext.data.Store({ proxy: new Ext.data.XXXProxy({ ... }), reader: new Ext.data.XXXReader({ ... }) });
Store内部で生成しているProxyはデータを取得するクラス、Readerはそのデータを内部形式(Ext.data.Record)にマッピングするクラスです。
Ext.dataパッケージにはProxy、Reader、Storeに関連するクラスが複数存在しているので、用途に応じた使い分けが必要です。
Proxy
- Ext.data.DataProxy (Extends: Observable)
ベースクラス(抽象クラス)
- Ext.data.MemoryProxy (Extends: DataProxy)
メモリ(変数)からデータを取得する際に利用
- Ext.data.HttpProxy (Extends: DataProxy)
HTTP経由でデータを取得する際に利用
- Ext.data.ScriptTagProxy (Extends: DataProxy)
JSONP形式で提供されているデータを取得する際に利用
Reader
- Ext.data.DataReader (Extends: Object)
ベースクラス(抽象クラス)
- Ext.data.XmlReader (Extends: DataReader)
- Ext.data.JsonReader (Extends: DataReader)
- Ext.data.ArrayReader (Extends: JsonReader)
Array(配列)からExt.data.Recordへのマッピング
Store
- Ext.data.Store (Extends: Observable)
ベースクラス
- Ext.data.SimpleStore (Extends: Store)
ArrayからStoreを生成するヘルパークラス
- Ext.data.JsonStore (Extends: Store)
JSONからStoreを生成するヘルパークラス
- Ext.data.GroupingStore (Extends: Store)
グルーピングレコードを実装するStoreを生成するクラス
ArrayからStore生成
Ext.data.MemoryProxyに直接Arrayを指定してデータを生成し、Ext.data.ArrayReaderで各配列の要素にマッピングします。ここで指定したnameプロパティは後ほどGridを生成する際に利用します。
var store = new Ext.data.Store({ proxy: new Ext.data.MemoryProxy([ [1, 'Bill', 'Gardener'], [2, 'Ben', 'Horticulturalist'], [3, 'Mark', 'Programer'] ]), reader: new Ext.data.ArrayReader({}, [ {name: 'id'}, {name: 'name'}, {name: 'occupation'} ]) }); store.load();
また、MemoryProxyとArrayReader組み込み済みのExt.data.SimpleStoreを利用すれば手軽に生成できます。
var store = new Ext.data.SimpleStore({ data: [ [1, 'Bill', 'Gardener'], [2, 'Ben', 'Horticulturalist'], [3, 'Mark', 'Programer'] ], fields: [ {name: 'id'}, {name: 'name'}, {name: 'occupation'} ] });
JSONからStore生成
Arrayと同じ内容のStoreをJSONから生成します。通信して取得するのでExt.data.HttpProxyを指定し、Ext.data.JsonReaderでマッピングの設定を行います。
var store = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({ url: 'get-json.php' }), reader: new Ext.data.JsonReader({ root: 'rows', //各データを保持しているキー totalProperty: 'results' //データ数を保持しているキー },[ {name: 'id'}, {name: 'name'}, {name: 'occupation'} ]) }); store.load();
JSONの場合もExt.data.JsonStoreを利用すれば手軽に利用可能です。JsonStoreはHttpProxyとJsonReaderが組み込み済みなので下記のように両方まとめて指定できます。
var store = new Ext.data.JsonStore({ url: 'get-json.php', root: 'rows', totalProperty: 'results', fields: [ {name: 'id'}, {name: 'name'}, {name: 'occupation'} ] }); store.load();
<?php echo <<<E { 'results': 3, 'rows': [ {'id': 1, 'name': 'Bill', occupation: 'Gardener'}, {'id': 2, 'name': 'Ben' , occupation: 'Horticulturalist'}, {'id': 3, 'name': 'Mark' , occupation: 'Programer'} ] } E;
XMLからStore生成
Arrayと同じ内容のStoreを今度はXMLから生成します。内容はJSONとほぼ同じなので省略。
var store = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({ url: 'get-xml.php' }), reader:new Ext.data.XmlReader({ record: 'row', totalRecords: 'results' }, [ {name: 'id'}, {name: 'name'}, {name: 'occupation'} ]) }); store.load();
<?php header('Content-type: text/xml;'); echo <<<E <?xml version="1.0" encoding="UTF-8"?> <dataset> <results>3</results> <row> <id>1</id> <name>Bill</name> <occupation>Gardener</occupation> </row> <row> <id>2</id> <name>Ben</name> <occupation>Horticulturalist</occupation> </row> <row> <id>3</id> <name>Mark</name> <occupation>Programer</occupation> </row> </dataset> E;
Gridで利用する
最後に上記で生成したStoreを利用してGridを生成する方法です。Gridを生成するにはStoreのデータをどのように表示するかをExt.grid.ColumnModelで指定します。headerがGridに表示される列のヘッダ名称、dataIndexがReaderでマッピングしたnameプロパティです。
var cm = new Ext.grid.ColumnModel([{ header: 'ID', dataIndex: 'id', width: 50 },{ header: 'Name', dataIndex: 'name', width: 100 },{ header: 'Occupation', dataIndex: 'occupation', width: 100 }]); var grid = new Ext.grid.GridPanel({ title: 'Sample', collapsible: true, frame: true, width: 300, height: 200, store: store, cm: cm, renderTo: Ext.getBody() }); //Ext.data.Recordオブジェクトを取得 grid.on('rowdblclick', function(grid, rowIndex, e){ var record = grid.getStore().getAt(rowIndex); console.log(record); });
単純にGridに表示するために必要な情報はこんなところでしょうか。