同一テーブルでプロパティ項目を変更して永続化
[4]クライアント側のプログラム
リスト2は、Webクライアント側のプログラムです。図3から図5の画面表示を行い、リスト1で示したビーンズに対して登録データを送信します。
リスト2: addItem.htm
<!DOCTYPE html> <html> <head> <meta charset=utf-8> <title>商品マスタ登録</title> <link type="text/css" rel="stylesheet" href="/csslib/style.css"/> <script type="text/javascript" src="/dwr/interface/itemBean.js"></script> <script type="text/javascript" src="/dwr/engine.js"></script> <script type="text/javascript" src="/dwr/util.js"></script> <script type="text/javascript" src="/jslib/jquery-1.4.2.min.js"></script> <script type="text/javascript"> //<![CDATA[ window.resizeTo(380,530); window.moveTo(10,10); var kind = "desktop"; var query = {}; $(function(){ $("#type").val("デスクトップPC"); $("#kind").click(function(e){ //(1) var stitle ="", spectag =""; kind=e.target.id; if(kind=="desktop"){ stitle ="デスクトップPC"; spectag = '<table width="330" border="1" bgcolor="#eeeeee">' + '<tr><th width="100">CPU</th>' + '<td><input type="text" size="30" id="cpu"/></td></tr>' + '<tr><th>メモリ</th><td><input type="text" id="memory"/></td></tr>' + '<tr><th>OS</th><td><input type="text" id="os"/></td></tr>' + '<tr><th>ステータス</th><td id="status"></td></tr></table>'; }else if(kind=="display"){ stitle ="液晶ディスプレイ"; spectag = '<table width="330" border="1" bgcolor="#eeeeee">' + '<tr><th width="100">サイズ</th>' + '<td><input type="text" size="30" id="size"/></td></tr>' + '<tr><th>ステータス</th><td id="status"></td></tr></table>'; }else if(kind=="printer"){ stitle ="プリンタ"; spectag = '<table width="330" border="1" bgcolor="#eeeeee">' + '<tr><th width="100">用紙サイズ</th>' + '<td><input type="text" id="papersize"/></td></tr>' + '<tr><th>解像度</th>' + '<td><input type="text" id="resolution"/></td></tr>' + '<tr><th>ステータス</th><td id="status"></td></tr></table>'; }else{ spectag = '<table width="330" border="1" bgcolor="#eeeeee">' + '<tr><th colspan="2">選択エラー</th></tr>' + '</table>'; } $("#stitle").text(stitle); $("#type").val(stitle); $("#spec").html(spectag); }); $("#add").click(function(e){ //(2) query["kind"]=kind; query["itemNo"]=$("#itemNo").val(); query["type"]=$("#type").val(); query["itemName"]=$("#itemName").val(); query["price"]=$("#price").val(); if(kind=="desktop"){ query["cpu"]=$("#cpu").val(); query["memory"]=$("#memory").val(); query["os"]=$("#os").val(); }else if(kind=="display"){ query["size"]=$("#size").val(); }else if(kind=="printer"){ query["papersize"]=$("#papersize").val(); query["resolution"]=$("#resolution").val(); } itemBean.addItem(query, function(stat){ //(3) $("#status").text(stat); clear(); }); }); }); function clear(){ //(4) $.each(["itemNo", "type", "itemName", "price"], function(){ $("#" + this).val(""); }); $("#itemNo").focus(); } //]]> </script> </head> <body bgcolor="#cccccc"> <h2 style="color: #aa0022">コンピュータ商品登録 <input type="button" id="add" value=" 登録 "/> </h2> <div id="kind"> <input type="radio" name="pc" id="desktop" checked="checked"/>デスクトップPC <input type="radio" name="pc" id="display" />液晶ディスプレイ <input type="radio" name="pc" id="printer" />プリンタ </div> <table width="330" border="1" bgcolor="#eeeeee"> <tr><th id="stitle" colspan="2">デスクトップPC</th></tr> <tr> <th width="100">製品番号</th> <td><input type="text" size="12" id="itemNo"/></td> </tr> <tr><th>タイプ</th><td><input type="text" id="type"/></td></tr> <tr><th>製品名</th><td><input type="text" size="28" id="itemName"/></td></tr> <tr><th>価格</th><td><input type="text" size="10" id="price"/></td></tr> </table> <nobr id="spec"> <table width="330" border="1" bgcolor="#eeeeee"> <tr><th width="100">CPU</th><td><input type="text" id="cpu"/></td></tr> <tr><th>メモリ</th><td><input type="text" id="memory"/></td></tr> <tr><th>OS</th><td><input type="text" id="os"/></td></tr> <tr><th>ステータス</th><td id="status"></td></tr> </table> </nobr> </body> </html>
このクライアント・プログラムでは、jQueryとDWRの非同期通信メソッドを使用して、サーバーに登録データを送信しています。この連載は、Low-Level APIでのデータ・ストア・アクセスがテーマなので、ここではポイントだけを解説します。
[クライアント側のプログラム処理]
リスト2の(1)は、画面上部のラジオ・ボタン・クリックで製品種別を選択したときに起動される、匿名関数です。e.target.id;で取得されるkindを使用し、基本項目の下に表示されます。選択項目を、図3(b、c)のように、動的に変更表示します。
リスト2の(2)は、「登録」ボタンをクリックしたときに起動される、匿名関数処理です。ここでは、連想配列のqueryに、画面入力データをセットしています。製品種別によって登録項目が異なるため、if文による判断で登録内容を判別しながら処理を行います。queryへのデータ・セットがすべて完了すると、(3)の非同期通信処理に移ります。
リスト2の(3)のように、クライアント側のJavascript処理は、全体としてはjQueryを使用した内容になっています。しかし、サーバーとの非同期通信処理については、DWRのクラス・メソッドを用いた処理内容になっています*4。
- [*4] 非同期通信には、jQueryの$.postなどを使用することもできます。しかし、この場合は、サーバー側でサーブレットを記述する必要があります。もっとも、ユーザー記述のサーブレットを使用する場合でも、サーバー・サイドでDWRデバッグ機能を利用できます。
DWRの非同期通信処理は、大変シンプルです。サーバー側で稼働するitemBeanのaddItemメソッドをそのまま呼び出す形式で記述すればよく、この場合、引数としては、永続化データがセットされている連想配列のqueryを指定するだけです。サーバー側での永続化処理の完了後にクライアント側にステータス情報が返されると、第2引数の匿名関数が起動され、ステータス表示が行われます。
[永続化データの管理画面表示]
最後に、このサンプルのように、異なるプロパティ項目を含むエンティティが登録された場合、App Engineの管理者画面(Datastore Viewer)から参照すると、どのように表示されるのかを確認してみます。
図6: 登録後のエンティティ表示(クリックで拡大) |
図6は、このサンプルで登録されたエンティティ項目を、管理者画面で確認した内容です。itemMasテーブルにはエンティティが3つ登録されていますが、それぞれ登録されているプロパティ項目が違います。各登録処理でプロパティ名に対応する値がない場合は"