処理を担当するActionScriptクラスです。通信周りは相変わらず非常にシンプルなコードになっているので、今回は解説を省略します(実案件でも送受信するデータに対する処理の多少はありますが、直感的にサーバのサービスを呼び出すことには変わりません)。
AdvancedDataGridの1列目の列番号表示用に「ラベルファンクション」を利用しています。ラベルファンクションはデータ文字列を加工して表示する場合に利用する便利な関数です。「セルに画像を表示する」といった見た目の変更はアイテムレンダラーやアイテムエディターを用います。
UserForm.mxmlのAdvancedDataGridで列を定義するタグでは、以下のようにラベルファンクションを定義しています。
<mx:AdvancedDataGridColumn headerText="No" width="50" labelFunction="userLogic.rowNumLabelFunction" sortable="false"/>
これによりヘッダがNoで表される列はUserエンティティの何らかのデータを表示するのではなく、labelFunctionが返すデータを表示することになります。実際のrowNumLabelFunctionは以下のようになっています。
public function rowNumLabelFunction(object:Object, column:AdvancedDataGridColumn):String { var rowIndex:int = userList.getItemIndex(object) + 1; return String(rowIndex); }
objectには、AdvancedDataGridの1行1行に対応したエンティティが渡されます。ここではそのエンティティがもともとユーザー一覧データの何行目かを取得して返しています。
また、データフィルタ処理を行っている部分も見ていきましょう。各コンボボックス、テキスト入力にはchange属性が設定されています。
<mx:ComboBox id="bloodCombo" dataProvider="{AppConsts.BLOOD_TYPE}" change="userLogic.bloodChangeHandler(event)" />
このchangeイベントのハンドラに指定されている処理がフィルタ処理を行っています。
public function bloodChangeHandler(event:ListEvent):void { if(userList != null) { if(view.bloodCombo.selectedItem.value == "全血液型") { selectedBloodType = ""; } else { selectedBloodType = view.bloodCombo.selectedItem.value; } // フィルタファンクション userList.filterFunction = doFilter; // フィルタ処理を実行 userList.refresh(); // 表示件数更新 updateHitNum(); } }
selectedBloodTypeはフィルタ条件を保持する変数です。userListがAdvancedDataGridのdataProviderに指定されているデータで、このArrayCollection型のデータにはfilterFunctionを指定でき、関数指定後にrefreshによりフィルタ処理を実行しています。ここでは、フィルタファンクションとしてdoFilterメソッドを代入しています。
doFilterメソッドは3つのフィルタ用のコンボボックスとテキスト入力からのデータを「selected○○」という変数を通じて処理を行っています。
private function doFilter(value:Object):Boolean { var bloodTypeCheck:Boolean; var preCheck:Boolean; //性別とEメールによるフィルタ処理部分のソースは省略 if(selectedBloodType == "" || selectedBloodType == null) { bloodTypeCheck = true; } else { bloodTypeCheck = (User(value).bloodtype == selectedBloodType); } if(selectedPre == "" || selectedPre == null) { preCheck = true; } else { preCheck = (User(value).prefecture == selectedPre); } return ( sexCheck && bloodTypeCheck && preCheck && emailCheck); }
フィルタファンクションは「各行が表示すべきかすべきでないか」の判断を行う関数です(戻り値がBoolean)。フィルタファンクションの引数には各行のエンティティが渡されます。上記の血液型のフィルタ処理では各行の血液型がコンボボックスの血液型に一致すればtrueとしています。
最後のreturn部分ですべてのフィルタ処理を合格したデータだけが抽出されるような値を返しています。このフィルタ処理が今回の場合1万件のデータに対して毎回瞬時に適応されます。
ちょっとした装飾で結構実用的な画面のアプリケーションになっていると思います。
今回Java側アプリケーションで解説する部分は特にありませんでした。シンプルなソースですので、前回までの記事と併せてソースを読んでもらえれば、十分理解していただける内容かと思います。
ただ、今回ユーザーのデータを「Record」という名前のテーブルに保存しているので、そのテーブルをUserエンティティで受け取れるようにUser.javaでマッピングを行っています。
/** * レコードテーブルに対応したエンティティ */ @Entity @Table(name="Record") public class User implements Serializable {
簡単ですね。カラムもAAA_BBBBの形で作っていないので一部マッピングを行っています。
/** prefectureCode */ @Column(name="prefectureCode") public String prefectureCode;
今回用意したデータベースはテーブル名もカラム名もJava、ActionScriptのエンティティの命名規則に準じたものになっています(キャメルケース)。
今回エンティティは手でコーディングしましたが、テーブルから自動生成してくれるツールも各種存在しています(S2JDBC-Genなど)。
今回は1万件データを1度に表示するアプリケーションを作ってみました。実際に動かしてみると結構描画が速いことを体感していただけると思います。この高パフォーマンスは以下の2つによって実現されています。
DataGridのパフォーマンス設計はリッチなDataGridになればなるほど難しくなりますが、適切に設計するといままでにないアプリケーションのインターフェイスを実現できる可能性は十分にあります。そんなFlexの可能性を、今回のアプリケーションを通じて感じていただければ幸いです。
次回はいよいよ最終回です。前回までのクイズアプリケーションのFlex部分のアーキテクチャを最新のアーキテクチャに作り替えて、開発生産性の高いものにリファクタリングしてみたいと思います。また、お伝えしていないBlazeDS、S2BlazeDS関連の設定などに関してもお伝えする予定です。
@IT関連記事
いまさら聞けないFlex、そして、いまこそ入門のとき!?
Flex 3正式版リリース! Flexの過去・現在・未来 先日ついに正式リリースされたFlashベースのRIA技術Flex 3。いまが入門に最適なFlexの過去・現在・未来を一挙に解説
「リッチクライアント & 帳票」フォーラム 2008/3/31
作って学ぶAIRウィジェットの基礎→応用
最近よく聞くAdobe AIRって何だっけ? ウィジェットを簡単に作れるらしいけど…… と曖昧な知識のあなたに贈る超入門連載。楽しいサンプルを作って基礎から応用まで学ぼう
Webアプリの常識をJSPとStrutsで身につける
JSP/サーブレット+StrutsのWebアプリケーション開発を通じて、Java言語以外の開発にも通用するWebアプリケーション全般の広い知識・常識を身に付けるための連載です。初心者・中堅・ベテランも大歓迎!
福田 寅成(ふくだ ともなり)
クラスメソッド株式会社 情報システム部 テクニカルスペシャリスト
大手SIerでの長いJava開発経験を経てクラスメソッドに。 Java、JavaScript/Ajax、Flex、AIR、C#など、さまざまな分野に関する技術調査研究、および業務アプリケーション開発に携わる。 FlexやAIRの開発依頼はコチラ
Copyright © ITmedia, Inc. All Rights Reserved.