Open Laszloを使って作るリッチクライアント
(6)
Laszlo Applicationのデータ形式とバインディング


浅野守
2005/9/27

本連載ではオープンソースのリッチクライアント製品として注目を集める「Open Laszlo」を解説している。Laszloはサーバサイドで生成したコンテンツをFlashとしてクライアントのWebブラウザに配信するもので、Macromedia社のFlexと非常によく似たアーキテクチャを採用。Laszlo Applicationのプレイスメントが理解できたら、最終回の今回はいよいよ、データバインディングに挑戦してみよう。

Laszlo Application配置の2つの方法

 前回(Laszlo Application配置の2つの方法)までで、Laszlo Applicationの実装方法、Laszlo Applicationの2つの配置方法について説明しました。

 今回は、LZXでのデータの扱い方について概要を説明します。

 LZXでは以下のようなデータ操作が可能です。

  • DatasetとしてLaszlo Applicationにデータを格納する
  • リモートにあるデータソースからデータを受け取る
  • Webサービスを介してデータを受け取る
  • 実行時にデータを生成、操作する
  • ユーザーインターフェイスにデータを宣言的にバインドする

 リモートのデータソースについて、今回は、受信方法についてのみ説明いたします。

データ形式

 LZXで操作するデータはXML形式で扱われ、XPathのサブセットを使用してアクセスします。

Dataset

 datasetタグを使用してcanvas内にデータを定義することができます。(下記)このように定義されたデータをローカルデータと呼びます。

<canvas>
  <dataset name=”shelf”>
   <bookshelf>
      <book binding=”paperback”>
        <titile>Acts of the Apostles</title>
       <author>John F.X. Sundman</author>
       <publisher>Rosalita Associates</publisher>
       <price>15.00</price>
       <year>1999</year>
       <category>thriller</category>
       <rating>4.5</rating>
     </book>
     <book>
    …(省略)
     </book>
   </bookshelf>
  </dataset>
</canvas>

 このdatasetにはcanvas.shelfという表記でアクセスできます。

LZXからのデータ操作

 LZXからは、dataset、datapath、datapointerタグを使用してデータ操作を行います。

datasetとdatapath

 ではdatasetとdatapathを使用してローカルデータにアクセスしてみましょう。

<canvas heitht="80" width="500">
 <dataset name="myData">
  <myXML>
   <person show="simpsons">
     <firstName>Homer</firstName>
     <lastName>Simpson</lastName>
   </person>
   <person show="simpsons">
     <firstName>Marge</firstName>
     <lastName>Simpson</lastName>
   </person>
   <person show="simpsons">
     <firstName>Montgomery</firstName>
     <lastName>Burns</lastName>
   </person>
  </myXML>
 </dataset>


 <text datapath="myData:/myXML[1]/person[1]/firstName[1]/text()"/>
</canvas>

 上記のコードでは <dataset name="myData"> で定義したデータセットを、textタグのdatapath属性のXPath値で指定して、textタグにバインドしています。このコードを実行するとブラウザ上に "Homer" と表示されます。

 このコードでは先頭のpersonエレメントのfirstNameエレメントのテキストを絶対パスで記述しています。しかし、複数のエレメントデータを表示する際に、いちいち絶対パスを記述するのでは面倒です。その場合は、viewタグでくくることによりXPathの一部を省略することができます。

<view name="rowOfData" datapath="myData:/myXML[1]/person[1]/">
 <simplelayout axis="x" />
 <text datapath="firstName/text()"/>
 <text datapath="lastName/text()"/>
 <text datapath="@show"/>
</view>

 上記のコードではviewタグの属性datapathにmyData:/myXML[1]/person[1]/ を指定することでcanvasタグのdatapathの記述はviewタグのdatapath値からの相対パスで記述しています。

 複数のエレメントデータの表示については、<simplelayout axis="x" />タグを指定することで、データをx軸方向に並べて表示することができます(画面1)。

画面1 複数のエレメントデータの表示

 上記のコードでは複数のエレメントデータを1行で表示していますが、行が繰り返すような場合は、viewタグとsimplelayoutタグをネストすることで、複数行で表示することが可能です。

<view name="myTable">
 <simplelayout axis="y"/>

  <view name="rowOfData" datapath="myData:/myXML[1]/person[1]/">
  <simplelayout axis="x" />
  <text datapath="firstName/text()"/>
  <text datapath="lastName/text()"/>
  <text datapath="@show"/>
 </view>
</view>

画面2 複数のエレメントデータの複数行での表示

データソース

 これまでの説明はドキュメント内(LZXソースコード内)に直接記述されたデータの取り扱いですが、直接記述するほかに、外部ファイルに記述してインクルードすることや、サーバからHTTPで取得することが可能です。

インクルードデータ

  ドキュメント内に直接記述していたdatasetを外部ファイルに記述してインクルードする方法です。記述方法は下記のようになります。データはコンパイル時にロードされます。

<dataset name="データセット名" src="xmlファイルへの相対パス" />
例:<dataset name="myData" src="myXMLDoc.xml" />

 この例では、ロードされたデータはmyDataという名前のデータセットになります。

HTTPデータ

  URLで指定されたデータソースから実行時にHTTP経由でデータをロードすることができます。データソースはXMLを返す必要があります。記述方法は下記のようになります。

<dataset name="データセット名" autorequest="trueまたはfalse" type="http" src="URLまたはxmlファイルへの相対パス" />

例:<dataset name="myData" autorequest="true" type="http" src="myXMLDoc.xml" />
例:<dataset name="myData" src=http://www.datasetserver.com/cgi-bin/getdata.cgi />

 autorequest属性の値がtrueの場合は、アプリケーションがロードされるとすぐにデータがロードされます。src属性の値がhttp://を含んでいる場合はtype属性を省略することができます。

 データのロードはsrc属性の値がsetQueryString() メソッドやsetURL() メソッドで変更されるタイミングでロードすることや、doRequest() メソッドで任意のタイミングでロードすることができます。

Datapointer

  datapointerを使用するとスクリプト中でのデータ操作を行うことができます。下記のコードを実行すると、personエレメントのshow属性の値がsouth parkのデータが、デバッグウィンドウに表示されます。

<canvas height="180" width="500" debug="true">
  <dataset name="myData">
   <myXML>
    <person show="simpsons">
     <firstName>Homer</firstName>
     <lastName>Simpson</lastName>
    </person>
    <person show="simpsons">
     <firstName>Marge</firstName>
     <lastName>Simpson</lastName>
    </person>
    <person show="simpsons">
     <firstName>Montgomery</firstName>
     <lastName>Burns</lastName>
    </person>
    <person show="south park">
     <firstName>Eric</firstName>
     <lastName>Cartman</lastName>
    </person>
    <person show="south park">
     <firstName>Stan</firstName>
     <lastName>Marsh</lastName>
    </person>
   </myXML>
  </dataset>


  <datapointer xpath="myData:/" ondata="processData()">
   <method name="processData">
    this.selectChild(2);
    do {
     if (this.xpathQuery( '@show' ) == 'south park') {
        Debug.write(this.xpathQuery('firstName/text()'));
     }
    } while (this.selectNext());
   </method>
  </datapointer>
</canvas>

画面3 personエレメントのshow属性の表示

 <datapointer xpath="myData:/" ondata="processData()"> では、データセットmyDataのドキュメントルートがdatapointerにひも付けられ、データロード時にprocessData() メソッドが呼び出されるように記述されています。

  processData() メソッドでは最初にthis.selectChild(2) で先頭のpersonエレメントを選択し、this.xpathQuery('@show') でpersonエレメントのshow属性の値を取り出してsouth parkと比較しています。一致する場合は、Debug.write(this.xpathQuery('firstName/text()') でfirstNameエレメントの値をデバッグウィンドウに出力します。while文中のthis.selectNext() でpersonエレメントが存在する限り処理を続けています。

 以上がLZXでのデータ表現およびデータ操作の概要です。データとユーザーインターフェイスとのバインディングの詳細、データ更新のタイミングとビュー更新のタイミングのコントロールについては、「Software Developer's Guide to Laszlo Applications」の第32章「Data Access and Binding」に詳細が記述されています。この連載がオープンソースでリッチクライアントを構築する際にお役に立てば幸いです。ご愛読ありがとうございました。




HTML5 + UX フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

HTML5+UX 記事ランキング

本日 月間