2.1. Readインターフェース
dojo.dataが扱うデータストアは次の図のようなイメージでデータを格納します。見た目はリレーショナル・データベースの表に似ていますね。JavaScriptのオブジェクトを要素とする配列のようでもあります。
データストアが格納する一つ一つのデータをアイテム(item)と呼びます。アイテムはデータとしていくつかの属性(attributes)を持つことができます。
属性は属性名(attribute)と属性値(value)のペアです。属性は複数の値を持つこともあります。アイテム(item)、属性名(attribute)と属性値(value)はこの後で紹介するAPIで引数として登場するので頭に入れておきましょう。
2.1.1. fetch()メソッド
Readインターフェースに定義されているメソッドのうち一番重要なのはfetch()です。データストアに格納したデータを利用するときは、まずこのメソッドを使って条件に合うアイテムを取得します。
メソッド | 説明 |
fetch: function(/* Object */ keywordArgs) | keywordArgsに指定した条件にマッチしたデータを抜き出して返します。 |
keywordArgsには次のプロパティをもつオブジェクトを渡します。すべての引数は必須ではありませんが、データストアのデータに対して処理を行いたいのならばコールバック関数を最低1つ以上は指定することになります。
プロパティ名 | 型 | 説明 |
query | String または Object | クエリー文字列、またはオブジェクト |
queryOptions | Object | queryとともに渡すオプション |
start | int | クエリー開始位置 |
count | int | クエリー件数 |
sort | Array | ソートキーを表すオブジェクトの配列 |
onBegin | Function | 開始時呼ばれるコールバック関数 |
onItem | Function | アイテム1つずつに対して呼ばれるコールバック関数 |
onComplete | Function | 完了時呼ばれるコールバック関数 |
scope | Object | コールバック関数のスコープオブジェクト |
query, queryOptionsはデータストアからアイテムを抜き出す条件を指定するための引数です。要求される引数の型や実際に行われる処理はデータストアの実装に依存します(例えばサーチエンジンから結果を取得するデータストアではqueryはサーチエンジンに渡す検索クエリー文字列そのものでしょう。またデータベースからデータを読み込むデータストアにとってはSQL文がqueryになりますね。queryの処理時に渡す必要があるオプションがあればqueryOptionsとして渡します)。
startには取得するデータの先頭の番号を、countには取ってくる件数を指定します(これも実際にどう動作するかは実装に依存しますが、サーチエンジンから結果を返すデータストアなら検索結果のうちstart番目からcount件返せ、と指示することになります)。
sortには{attribute: 属性名, descending: trueまたはfalse}というソートキーを表すオブジェクトの配列を渡します。データストアがデータをソートする能力を持っていればこのメソッドによりデータがソートされます。
onBegin, onItem, onCompleteは抜き出されたitemを処理するためのコールバック関数です。
- onBegin: function(size, request); --- fetch()が処理を開始する時点、つまりonItem()が1番目のアイテムを処理する前に一度だけ呼ばれます。sizeには処理するデータの総数(不明な場合は-1)が入っています。
- onItem: function(item, request); --- fetch()が条件に合うアイテムを1つ抜き出すたびに呼ばれます。条件に合うアイテムの総数回呼ばれることになります。
- onComplete: function(items, request); --- fetch()が処理を終了するとき呼ばれます。つまり最後のonItem()が呼ばれた後に一度だけ呼ばれます。itemsには処理の結果抜き出されたアイテムが配列で入っています。
このように登録したコールバック関数を呼び出してもらうデザインになっているのは、データソースはfetch()してすぐにデータの準備ができるとは限らないので、非同期で動作することを想定しているためです。
fetch()の返り値はdojo.data.api.Requestインターフェースのオブジェクトで、keywordArgsの情報を持つと同時にabort()メソッドが定義されています。fetch()の処理に時間がかかりすぎているときなどにabort()を呼び出すと処理を中断させることができます。
各コールバック関数の2番目の引数requestにも同じRequestオブジェクトが渡されます。
次の擬似コード例ではあるデータストアに格納しているアイテムをすべて取り出しますが、1つ取り出すたびに処理を行います。
var store = new some.example.store( ... ); /* Readインターフェースを実装する架空のデータストア */ var kerwordArgs = { /* query が指定されていないとき、fetch()はデータストアに格納された全アイテムを返す対象にします。 */ onItem: function(item,request) { var name = store.getValue(item, "name"); /* itemを引数にしてReadインターフェースのgetValue()を呼びます。 */ alert("名前: " + name); /* 各アイテムの name 属性の値を出力します。 */ } } var request = store.fetch(keywordArgs); /* 実際にfetch()を行い、登録されたコールバック関数に処理を移します。 */
次の擬似コードではqueryに指定した条件に合うアイテムがすべて準備できてからまとめて処理を行います。
var store = new some.example.store( ... ); /* Readインターフェースを実装する架空のデータストア */ var kerwordArgs = { query: "社員番号1???", // データストアの実装によってはワイルドカードを使うこともできます。この例では社員番号が1000番台のデータを抜き出すことになります。 */ onComplete: function(items,request) { alert("社員番号1000-1999の人数: " + items.length); /* itemsの総数を出力 */ } } var request = store.fetch(keywordArgs); // 実際にfetch()を行い、登録されたコールバック関数に処理を移します。
scopeにはコールバック関数が束縛されるスコープオブジェクトを指定します。コールバック関数中のthisはこのオブジェクトになります。dojo.hitch()のscope引数と同じ役割です。
2.1.2. その他のメソッド
fetch()メソッドで得られたitemを引数にして、コールバック関数中でReadインターフェースのさまざまなAPIを用いることで格納されたデータの情報を得ることができます。
残りのメソッドは表を見るだけで使い方の想像がつくと思いますので、以降では各メソッドの詳しい説明は割愛します。また通常使用しないメソッドは表から省いていますので、必要に応じてdojo.dataのAPIドキュメントもご覧ください。
メソッド | 説明 |
getValue: function(/* アイテム */ item, /* String */ attribute, /* Any? */ defaultValue) | itemがもつattribute名の属性の値を返します。 defaultValueはオプションで、itemがattribute名属性を持たないときおよび属性は持つが値を持たない(nullまたはundefined)とき返すデフォルト値を指定します。 |
getValues: function(/* アイテム */ item, /* String */ attribute) | itemがもつattribute名の属性値を(attribute名の属性が1つしかなくても)配列で返します。attribute名の属性値が存在しなければ空の配列が返ります。 |
getAttributes: function(/* アイテム */) | itemがもつすべての属性の属性名を配列で返します。 |
hasAttribute: function(/* アイテム */ item, /* String */ attribute) | アイテムitemが属性attributeをもつときtrueが返ります。 |
containsValue: function(/* アイテム */ item, /* String */ attribute, /* なんらかの値 */ value) | アイテムitemの属性attributeの属性値がvalueを含むときtrueを返します。 |
isItem: function(/* なんらかの値 */ something) | 値somethingがデータストアに格納しているアイテムならtrueが返ります。somethingがリテラルだったり、他のデータストアのアイテムだったりするとfalseになります。 |
isItemLoaded: function(/* なんらかの値 */ something) | 値somethingがデータストアのアイテムであり(つまりisItem(something)==true)、すでにデータストア上にロードされているときtrueになります(サーバーに問い合わせるデータストアなどでまだデータの準備ができていなければfalseになります)。 |
loadItem: function(/* Object */ keywordArgs) | keywordArgsに{item:アイテム, onItem: Function, onError: Function, scope: Object}の形式のオブジェクトを指定して、特定のitemをデータストアに明示的にロードします。 |
close: function(/*dojo.data.api.RequestまたはkeywordArgsまたはnull */ request) | データストアに現在のすべての接続の終了を指示します。動作はデータストアの実装によりますが、サーバーとの接続を終了するなどが起こるでしょう。 |
getLabel: function(/* アイテム */ item) | データストアにラベルが指定されているとき、itemのラベルを返します。ラベルはユーザーに分かりやすいデータの文字列表現です。 |
getLabelAttributes: function(/* アイテム */ item) | データストアのラベルは典型的にはデータの属性値からなります。ラベルを構成する属性値を配列で返すメソッドです。 |
次の擬似コードはhasAttribute()メソッドの使用例です。前項で述べたようにitemを引数とするメソッドはfetch()のコールバック関数中で使うことになります。
if( store.hasAttribute(item, "スキル") ) { …. // "スキル"属性があったときの処理 }
ここで注意しておきたい点として、多くのデータストア実装ではitemオブジェクトを覗いてみると属性や属性値がプロパティに格納されていますが、プロパティを通して直接参照や操作してはいけません。インターフェースのAPIを通じて操作・参照するようにしましょう(情報がどのように表現されているかはデータストアの実装によるので、プロパティに入っているとは限らないためです)。