<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<!-- EN-Revision: 24249 -->
<sect1 id="zend.dojo.data">
    <title>Zend_Dojo_Data: dojo.data エンベロープ</title>

    <para>
        Dojo には、データを扱うウィジェットのデータを抽象化するための
        <command>dojo.data</command> コンポーネントが存在します。
        このコンポーネントの持つ機能は、
        データストアのアタッチ、identifier フィールド (そしてオプションで
        label フィールド) に関連するメタデータの提供、
        問い合わせやソート用の <acronym>API</acronym>、
        データストアからのレコードの取得などがあります。
    </para>

    <para>
        <command>dojo.data</command> は、よく XmlHttpRequest と組み合わせて用いられます。
        動的なデータをサーバから取得するためにです。
        この基本的な仕組みは、QueryReadStore
        を拡張して <acronym>URL</acronym> とクエリ情報を指定するようにします。
        サーバ側からは、データを次のような <acronym>JSON</acronym> 形式で返します。
    </para>

    <programlisting language="javascript"><![CDATA[
{
    identifier: '<name>',
    <label: '<label>',>
    items: [
        { name: '...', label: '...', someKey: '...' },
        ...
    ]
}
]]></programlisting>

    <para>
        <classname>Zend_Dojo_Data</classname> は、
        このような構造をプログラムで作成したりそれを操作したり、
        配列や <acronym>JSON</acronym> にシリアライズしたりといった機能のシンプルなインターフェイスを提供します。
    </para>

    <sect2 id="zend.dojo.data.usage">
        <title>Zend_Dojo_Data の使用法</title>

        <para>
            もっともシンプルな使用法は、<command>dojo.data</command>
            に各アイテムの identifier フィールドの名前とアイテムの内容 (データ) を渡すことです。
            コンストラクタか、あるいは設定用メソッドで渡します。
        </para>

        <example id="zend.dojo.data.usage.constructor">
            <title>コンストラクタでの Zend_Dojo_Data の初期化</title>

            <programlisting language="php"><![CDATA[
$data = new Zend_Dojo_Data('id', $items);
]]></programlisting>
        </example>

        <example id="zend.dojo.data.usage.mutators">
            <title>設定用メソッドでの Zend_Dojo_Data の初期化</title>

            <programlisting language="php"><![CDATA[
$data = new Zend_Dojo_Data();
$data->setIdentifier('id')
     ->addItems($items);
]]></programlisting>
        </example>

        <para>
            アイテムをひとつずつ追加したり複数一括で追加したりするには、それぞれ
            <methodname>addItem()</methodname> および <methodname>addItems()</methodname>
            を使用します。
        </para>

        <example id="zend.dojo.data.usage.append">
            <title>Zend_Dojo_Data へのデータの追加</title>

            <programlisting language="php"><![CDATA[
$data = new Zend_Dojo_Data($identifier, $items);
$data->addItem($someItem);

$data->addItems($someMoreItems);
]]></programlisting>
        </example>

        <note>
            <title>常に identifier を使うこと!</title>

            <para>
                すべての <command>dojo.data</command> データストアは、identifier
                カラムがメタデータに存在することを必須としています。
                <classname>Zend_Dojo_Data</classname> でもそれは同じです。
                identifier のないアイテムを追加しようとすると、
                例外が発生します。
            </para>
        </note>

        <para>
            個々のアイテムは、次のいずれかとなります。
        </para>

        <itemizedlist>
            <listitem><para>
                連想配列
            </para></listitem>

            <listitem><para>
                <methodname>toArray()</methodname> メソッドを実装したオブジェクト
            </para></listitem>

            <listitem><para>
                その他のオブジェクト (<methodname>get_object_vars()</methodname> でシリアライズされます)
            </para></listitem>
        </itemizedlist>

        <para>
            これらのアイテムのコレクションをアタッチするには
            <methodname>addItems()</methodname> あるいは <methodname>setItems()</methodname>
            (既存のアイテムはすべて消去されます) を使用します。
            これを使用するときには、引数をひとつ指定します。
        </para>

        <itemizedlist>
            <listitem><para>
                配列
            </para></listitem>

            <listitem><para>
                <classname>Traversable</classname> インターフェイスを実装したオブジェクト
                (このインターフェイスは <classname>Iterator</classname> と
                <classname>ArrayAccess</classname> を含んでいます)。
            </para></listitem>
        </itemizedlist>

        <para>
            アイテムの label として働くフィールドを指定したい場合は
            <methodname>setLabel()</methodname> をコールします。
        </para>

        <example id="zend.dojo.data.usage.label">
            <title>Zend_Dojo_Data での label フィールドの指定</title>

            <programlisting language="php"><![CDATA[
$data->setLabel('name');
]]></programlisting>
        </example>

        <para>
            最後に、<classname>Zend_Dojo_Data</classname> のアイテムを
            <command>dojo.data</command> <acronym>JSON</acronym> 配列から読み込むには <methodname>fromJson()</methodname>
            メソッドを使用します。
        </para>

        <example id="zend.dojo.data.usage.populate">
            <title>JSON からの Zend_Dojo_Data の作成</title>

            <programlisting language="php"><![CDATA[
$data->fromJson($json);
]]></programlisting>
        </example>
    </sect2>

    <sect2 id="zend.dojo.data.metadata">
        <title>コンテナへのメタデータの追加</title>

        <para>
            Dojo コンポーネントの中には、
            <command>dojo.data</command> の中に追加のメタデータを必要とするものもあります。
            たとえば <command>dojox.grid.Grid</command> は、データを動的に
            <command>dojox.data.QueryReadStore</command> から取得できます。
            ページ移動を正しく行うには、返されるデータの中に <property>numRows</property>
            というキーのデータ (中身はクエリが返す行の数) が必要となります。
            これによりグリッドが、サーバ側へのリクエストをいつ送ったらいいのか、
            そしていつリクエストが不要になるのか
            (つまり最終ページに達するのがいつなのか) を知ることができるようになります。
            このテクニックを使用すると、大規模なデータセットをグリッドに表示させる際に
            データ全体をいちどに取得する必要はなくなります。
        </para>

        <para>
            <classname>Zend_Dojo_Data</classname> では、
            このようなプロパティをオブジェクトのメタデータとして設定できます。
            以下の使用例をご覧ください。
        </para>

        <programlisting language="php"><![CDATA[
// "numRows" を 100 に設定します
$data->setMetadata('numRows', 100);

// 複数の項目をいちどに設定します
$data->setMetadata(array(
    'numRows' => 100,
    'sort'    => 'name',
));

// メタデータの値を調べます
$numRows = $data->getMetadata('numRows');

// すべてのメタデータを取得します
$metadata = $data->getMetadata();

// メタデータを削除します
$data->clearMetadata('numRows');

// すべてのメタデータを削除します
$data->clearMetadata();
]]></programlisting>
    </sect2>

    <sect2 id="zend.dojo.data.advanced">
        <title>高度な使用法</title>

        <para>
            シリアライズ可能なデータコンテナとしての働きだけではなく、
            <classname>Zend_Dojo_Data</classname> にはデータを様々な方法で操作したり
            読み込んだりする機能もあります。
        </para>

        <para>
            <classname>Zend_Dojo_Data</classname> は、インターフェイス
            <classname>ArrayAccess</classname>、<classname>Iterator</classname> および
            <classname>Countable</classname> を実装しています。
            そのため、データコレクションをまるで配列であるかのように使用できます。
        </para>

        <para>
            すべてのアイテムは、その identifier フィールドを用いて参照します。
            identifier は一意でなければならないので、
            この値を使用すればレコードを特定できるのです。
            参照する方法には、<methodname>getItem()</methodname>
            メソッドを使用するものと配列表記を使用するものの 2 通りがあります。
        </para>

        <programlisting language="php"><![CDATA[
// getItem() を使用します
$item = $data->getItem('foo');

// あるいは配列表記を使用します
$item = $data['foo'];
]]></programlisting>

        <para>
            identifier がわかれば、それを使用してアイテムを取得したり、
            あるいは更新したり削除したり作成したり調べたりできます。
        </para>

        <programlisting language="php"><![CDATA[
// アイテムの更新あるいは作成
$data['foo'] = array('title' => 'Foo', 'email' => 'foo@foo.com');

// アイテムの削除
unset($data['foo']);

// アイテムの確認
if (isset($data[foo])) {
}
]]></programlisting>

        <para>
            すべてのアイテムをループ処理することもできます。
            内部的には、すべてのアイテムは配列として格納されています。
        </para>

        <programlisting language="php"><![CDATA[
foreach ($data as $item) {
    echo $item['title'] . ': ' . $item['description'] . "\n";
}
]]></programlisting>

        <para>
            count で、アイテムの総数を調べることも可能です。
        </para>

        <programlisting language="php"><![CDATA[
echo count($data), " items found!";
]]></programlisting>

        <para>
            また、このクラスは <methodname>__toString()</methodname> を実装しているので、
            <acronym>JSON</acronym> への変換は単に echo するか文字列にキャストするだけで可能です。
        </para>

        <programlisting language="php"><![CDATA[
echo $data; // JSON 文字列として echo

$json = (string) $data; // 文字列へのキャスト == JSON へのキャスト
]]></programlisting>

        <sect3 id="zend.dojo.data.advanced.methods">
            <title>使用可能なメソッド</title>

            <para>
                上で説明したインターフェイスを実装するのに必要なメソッドに加えて、
                次のメソッドが使用可能です。
            </para>

            <itemizedlist>
                <listitem><para>
                    <methodname>setItems($items)</methodname>: 複数のアイテムを一度に設定し、
                    それまでそのオブジェクトに設定されていたアイテムをすべて上書きします。
                    <code>$items</code> は、配列あるいは
                    <classname>Traversable</classname> オブジェクトでなければなりません。
                </para></listitem>

                <listitem><para>
                    <methodname>setItem($item, $id = null)</methodname>:
                    個別のアイテムを設定し、オプションで明示的に identifier を渡します。
                    それまでにコレクション内にあったアイテムは上書きされます。
                    アイテムとして指定できるのは、連想配列、あるいは
                    <methodname>toArray()</methodname> を実装したオブジェクト、
                    あるいは public プロパティを持つそれ以外のオブジェクトです。
                </para></listitem>

                <listitem><para>
                    <methodname>addItem($item, $id = null)</methodname>:
                    個別のアイテムを追加し、オプションで明示的に identifier を渡します。
                    コレクション内にそのアイテムが既に存在する場合は例外が発生します。
                    アイテムとして指定できるのは、連想配列、あるいは
                    <methodname>toArray()</methodname> を実装したオブジェクト、
                    あるいは public プロパティを持つそれ以外のオブジェクトです。
                </para></listitem>

                <listitem><para>
                    <methodname>addItems($items)</methodname>: 複数のアイテムを一度に追加し、
                    それを任意のアイテムに追記します。新しく追加するアイテムの中に、
                    コレクション内の既存のアイテムの identifier
                    と一致するものがある場合は例外が発生します。
                    <varname>$items</varname> は、配列あるいは
                    <classname>Traversable</classname> オブジェクトでなければなりません。
                </para></listitem>

                <listitem><para>
                    <methodname>getItems()</methodname>: すべてのアイテムを、配列の配列形式で取得します。
                </para></listitem>

                <listitem><para>
                    <methodname>hasItem($id)</methodname>: 指定した identifier
                    のアイテムがコレクション内に存在するかどうかを調べます。
                </para></listitem>

                <listitem><para>
                    <methodname>getItem($id)</methodname>: 指定した identifier
                    のアイテムをコレクションから取得します。
                    返されるアイテムは連想配列となります。
                    マッチするアイテムがない場合は、 <constant>NULL</constant> 値を返します。
                </para></listitem>

                <listitem><para>
                    <methodname>removeItem($id)</methodname>: 指定した identifier
                    のアイテムをコレクションから削除します。
                </para></listitem>

                <listitem><para>
                    <methodname>clearItems()</methodname>:
                    コレクション内のすべてのアイテムを消去します。
                </para></listitem>

                <listitem><para>
                    <methodname>setIdentifier($identifier)</methodname>:
                    コレクション内の各アイテムの一意な識別子
                    (identifier) をあらわすフィールドの名前を設定します。
                </para></listitem>

                <listitem><para>
                    <methodname>getIdentifier()</methodname>:
                    identifier フィールドの名前を取得します。
                </para></listitem>

                <listitem><para>
                    <methodname>setLabel($label)</methodname>:
                    アイテムの表示用ラベルとして使用するフィールドの名前を設定します。
                </para></listitem>

                <listitem><para>
                    <methodname>getLabel()</methodname>: ラベル用フィールドの名前を取得します。
                </para></listitem>

                <listitem><para>
                    <methodname>toArray()</methodname>: オブジェクトを配列にキャストします。
                    配列には、最低限 'identifier' と 'items'
                    というキーが含まれ、オブジェクトにラベルフィールドが設定されている場合は
                    'label' というキーも含まれます。
                </para></listitem>

                <listitem><para>
                    <methodname>toJson()</methodname>: オブジェクトを <acronym>JSON</acronym>
                    表現にキャストします。
                </para></listitem>
            </itemizedlist>
        </sect3>
    </sect2>
</sect1>
<!--
vim:se ts=4 sw=4 et:
-->

