SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Flex基礎講座

Flex基礎講座(パート4):データモデルの利用

入力データを処理するデータモデルの作成とMVCの分離手法の解説

  • X ポスト
  • このエントリーをはてなブックマークに追加

新規従業員用モデルの追加

 FlexのModelコンポーネントは、その使い易さから想像できないほどパワフルです。ここでは、ユーザーが入力したデータを取得するためにモデルを利用し、ハンドラメソッドがフォーム要素からデータを分離できるようにします。この場面でモデルを利用する際のポイントは、モデルがActionScriptのオブジェクトを生成する点です。Modelブロックの中にXMLタグをネストすれば、オブジェクトにプロパティを追加することができます。したがって、次に示すMXMLとActionScriptのコードは、基本的に同じオブジェクトを生成することになります。

MXML
<mx:Model id="myModel">
    <name>Maya</name>
    <position>System Architect</position>
</mx:Model>
ActionScript
var myModel:Object=new Object();
myModel.name="Maya";
myModel.position="System Architect";

 ここでMXMLのモデルを利用するメリットは、波括弧({ })を記述すれば、オブジェクトのプロパティをデータの値にバインドできることです。

 <name>{nameInput.text}</name>
  1. Applicationブロックの最初にModelを追加し、「id="newEmpModel"」を設定します。
  2. <mx:Model id="newEmpModel">
    </mx:Model>
    
     
  3. Modelブロックの中に、ネスト化したXMLタグを利用して「fName」、「lName」、「location」の3つのプロパティを追加します。
  4. <fName></fName>
    <lName></lName>
    <location></location>
    
     
  5. この3つのXMLタグを、それぞれ「fNameInput.text」、「lNameInput.text」、「locCombo.selectedItem」にバインドします。
  6. <fName>{fNameInput.text}</fName>
    <lName>{lNameInput.text}</lName>
    <location>{locCombo.selectedItem}</location>
    
メモ
 これらのバインディングは、以前に作成したFormコントロールのプロパティへのバインディングです。

EmployeeモデルとLocationモデルの追加

 次に、XMLファイルの外部データをインポートするためのModelコンポーネントを2つ追加します。Modelコンポーネントを利用するもう1つのメリットは、整頓されたXMLを自動的にActionScriptのデータ構造に変換できる点です。XMLファイルをインポートするには、単にXMLファイルの完全な(あるいは一部の)URLをModelsource属性に設定するだけです。

  1. ダウンロードしておいたソースファイルの中の「employees.xml」ファイルを開くか、完成したソースコードをもとに「employees.xml」ファイルを作成します。このファイルのルートノードのallEmployeesには、全く同じ構成の2つのemployeeノードが含まれており、これらは、Modelのプロパティである、「employee」という名の配列になります。
  2.  
  3. newEmpModel」用のModelブロックの後に新たなModelを追加し、「id="empModel"」と「source="employees.xml"」を設定します。
  4. <mx:Model id="empModel" source="employees.xml"/>
    
     
  5. ダウンロードしておいたソースファイルの中の「locations.xml」ファイルを開くか、完成したソースコードをもとに「locations.xml」ファイルを作成します。このファイルのルートノードのlocationsには、一連のlocationノードが含まれています。これらは、Modelのプロパティでもある、「location」という名の配列になります。
  6.  
  7. empModelの後に新たなModelを追加し、「id="locModel"」と「source="locations.xml"」を設定します。
  8. <mx:Model id="locModel" source="locations.xml"/>
    
メモ
 これらのモデルへのバインディングは、既にComboBoxと「empGrid」用のDataGridを記述した際に作成済みです。バインディング情報が正しいかは、既に記述したコードを見直すことで確認できます。

DataControllerクラスのインスタンス化

 「data.mxml」ファイルに関する最後のステップは、DataControllerクラス(後ほど作成)のインスタンス化です。クラスのインスタンス化については、「Flex基礎講座(パート2):Flex電卓アプリケーションの作成」にて詳しく解説しましたが、ActionScriptのクラスはMXMLファイル内のタグを利用してインスタンス化することができます。ただし、この際、クラスの場所を規定するための名前空間の参照を含めなければ、Flexコンパイラはクラスを見つけることができません。

  1. Applicationタグの中に新たなxmlnsプロパティを追加し、このプロパティ値に名前空間の値、「"*"」を設定します。この際、接頭辞は不要です。
  2. <mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml"
    xmlns="*">
     
  3. Modelタグの後にDataControllerタグを追加し、「id="dataController"」を設定します。
  4. <DataController id="dataController"/>
    
メモ
 このオブジェクトは、既に、ボタンとデータグリッドのハンドラを指定した際に参照済みです。
  1. ファイルを保存します。これで「data.mxml」ファイルが完成しました。

Employeeクラスの作成

 次に、アプリケーションに必要な外部ActionScriptクラスの1つ目を作成します。Employee.asクラスは「data.mxml」が直接使用するものではありませんが、後ほど作成するDataControllerクラスにインポートされ、新たな従業員用のオブジェクトを生成する役割があります。

 クラス自体はシンプルであり、空のコンストラクタ関数、従業員の名前と所在地のためのプロパティ群、これらのプロパティ群に値を代入するためのメソッド、の3つの要素から構成されています。

 なお、ActionScriptクラスの構成については、「Flex基礎講座(パート2):Flex電卓アプリケーションの作成」にて解説しています。

  1. 新規ファイルを作成し、このファイルを「flex_tutorials」ディレクトリの中に「Employee.as」として保存します。
  2.  
  3. Employeeクラスのクラス定義と、空のコンストラクタ関数を追加します。
  4. class Employee
    {    
        // コンストラクタ関数    
        public function Employee()    
        {}
    }
    
     
  5. コンストラクタ関数の前に、タイプ「String」の3つの未定義プロパティ「fName」「lName」「location」を追加します。
  6. public var fName:String;
    public var lName:String;
    public var location:String;
    
     
  7. コンストラクタ関数の後にpublicメソッドのaddEmpDataを追加し、「fName」「lName」「location」の3つのString引数を受け付けるようにします。また、このメソッドの中で、各引数が、それぞれの引数と同じ名前のプロパティに代入されるようにしておきます。
  8. public function addEmpData(
    fName:String,lName:String,location:String):Void
    {    
        this.fName=fName;    
        this.lName=lName;    
        this.location=location;
    }
    
     
  9. ファイルを保存します。

DataControllerクラスの作成

 次に、「data.mxml」ファイルを作成した際にインスタンス化を指示しておいたDataControllerクラスを作成します。このクラスには「data.mxml」のイベントを処理するためのメソッドが含まれています。また、このクラスは次の2つの追加クラスをインポートします。

  • Employee:1つ前のステップで作成したActionScriptクラス
  • mx.managers.DragManager:ドラッグ&ドロップイベントを処理するためのプロパティやメソッドを含む、Flexクラスライブラリ内の静的クラス

 ここでは、DragManagerクラスの1つのプロパティだけを使用しますが、DragManagerクラスには他にもドラッグ&ドロップ関連のルールを実装するための多くの機能性が装備されています。詳細については、Flexドキュメンテーションを参照してください。

  1. 新規ファイルを作成し、このファイルを「flex_tutorials」ディレクトリの中に「DataController.as」として保存します。
  2.  
  3. ファイルの始めに、Employeeクラスとmx.managers.DragManagerクラスをインポートするためのimportステートメントを記述します。
  4. import mx.managers.DragManager;
    import Employee;
    
     
  5. importステートメントの後にDataControllerクラスのクラス定義と、空のコンストラクタ関数を追加します。
  6. class DataController
    {
        // コンストラクタ関数
        public function DataController()    
        {}
    }   
    

DataControllerのメソッドの追加

 DataControllerには次に挙げる3つのメソッドがあります。

  • addNewEmp()メソッドは「fName」「lName」「location」プロパティの備わったsrcオブジェクトを受け付け、そこからEmployeeクラスの一時的なインスタンスを生成します。この一時的なオブジェクトは、「dest」dataProviderに追加されます。srcdestが引数として渡されるので、このメソッドは、ボタンクリックとドラッグ&ドロップ操作の両データのコピーをすることができます。
メモ
 srcオブジェクトを直接追加する代わりに一時的なオブジェクトを作成する必要があるのは、オブジェクトが参照として渡されるからであり、こうすることで、srcオブジェクトに対して起こった変化を、自動的に「dest」dataProviderへ反映させることができます。
  • doDragEnter()メソッドは、オブジェクトの上をドラッグ中のオブジェクトが通過する際のイベントを処理します。このイベントでは、event.handledプロパティ(デフォルト設定:「false」)を利用して、オブジェクトがドラッグされたオブジェクトを受け付けることができるかの判断と、もし可能ならば、オブジェクトがドロップされた際にDragManagerのどの操作を行えばよいかを定義します(デフォルト設定:「なにもしない」)。
  •  
  • doDragDrop()メソッドは、ドラッグ中のオブジェクトがドロップされた際のイベントを処理します。この部分のロジックは、Flexが自動的に生成してハンドラに渡す、eventオブジェクトのプロパティとメソッドによって可能になります。
    • event.dragSource.dataForFormat("items")は、自動的に、ドラッグされたデータオブジェクトを含む配列を返します。
    • event.targetは、ドロップイベントが発生する場所のデータを受け取ることができる、オブジェクトを返します(データグリッドの場合、このプロパティはグリッドのdataProviderになります)。
  1. DataControllerのコンストラクタ関数の後にpublicメソッドの「addNewEmp()」を追加し、引数としてObjectタイプの「src」と「dest」を受け取り、戻り値がないように設定します。
  2. public function addNewEmp(src:Object,dest:Object):Void    
    {    
    }
    
     
  3. メソッドブロックの中でEmployeeタイプの変数、「tmpObj」を宣言し、これを新規Employeeオブジェクトとして初期化します。
  4. var tmpObj:Employee=new Employee();
    
     
  5. tmpObjに対して「Employee」のaddEmpData()メソッドを呼び出し、srcの「fName」「lName」「location」プロパティを引数として渡します。
  6. tmpObj.addEmpData(src.fName,src.lName,src.location);
    
     
  7. destに対して「dataProvider」のaddItem()メソッドを呼び出し、tmpObjを追加します。
  8. dest.addItem(tmpObj);
    
     
  9. 新たにdoDragEnter()という名のメソッドを追加し、eventを引数として受け付けます。このメソッドブロックの中に「event.handled=true」と「event.action=DragManager.COPY」を設定します。
  10. public function doDragEnter(event):Void    
    {        
        event.handled=true;
        event.action=DragManager.COPY;    
    }
    
     
  11. さらに、doDragDrop()という名のメソッドを追加し、このメソッドもeventを引数として受け付けるようにします。このメソッドブロックの中で、変数のitemsに「event.dragSource.dataForFormat("items")」、もう1つの変数destに「event.target」を、それぞれ代入します。
  12. public function doDragDrop(event):Void
    {        
        var items = event.dragSource.dataForFormat("items");
        var dest = event.target;
    }
    
     
  13. メソッド内に、items配列の1番目の要素とdestを渡すaddNewEmp()メソッドを追加し、ドラッグしたデータをドラッグ先のデータグリッドにコピーします。
  14. addNewEmp(items[0],dest);
    
     
  15. これで完成です。ファイルを保存してから「data.mxml」ファイルにブラウザし、動作を確認してください。新たな従業員の追加や、エンジニアリンググループまたはサポートグループのデータグリッドに従業員情報をドラッグする操作を試してください。
完成した「data.mxml」ファイルのコード
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml"
xmlns="*">
<mx:Model id="newEmpModel"> <fName>{fNameInput.text}</fName> <lName>{lNameInput.text}</lName> <location>{locCombo.selectedItem}</location> </mx:Model> <mx:Model id="empModel" source="employees.xml"/> <mx:Model id="locModel" source="locations.xml"/> <DataController id="dataController"/> <mx:HBox> <mx:Panel id="empPanel" title="Employee Data"
height="{engPanel.height+supPanel.height}">
<mx:DataGrid id="empGrid" dragEnabled="true"> <mx:dataProvider> {empModel.employee} </mx:dataProvider> <mx:columns> <mx:Array> <mx:DataGridColumn columnName="fName"
headerText="First Name" />
<mx:DataGridColumn columnName="lName"
headerText="Last Name" />
<mx:DataGridColumn columnName="location"
headerText="Location" />
</mx:Array> </mx:columns> </mx:DataGrid> <mx:Form> <mx:FormHeading label="Add New"/> <mx:FormItem label="First Name"> <mx:TextInput id="fNameInput"/> </mx:FormItem> <mx:FormItem label="Last Name"> <mx:TextInput id="lNameInput"/> </mx:FormItem> <mx:FormItem label="Location"> <mx:ComboBox id="locCombo"
dataProvider="{locModel.location}"/>
</mx:FormItem> </mx:Form> <mx:ControlBar> <mx:Button label="Add Employee"
click="dataController.addNewEmp (newEmpModel,empGrid.dataProvider)"/>
</mx:ControlBar> </mx:Panel> <mx:VBox> <mx:Panel id="engPanel" title="Engineering Group"
width="{empPanel.width}">
<mx:DataGrid dragEnter="dataController.doDragEnter(event)"
dragDrop="dataController.doDragDrop(event)">
<mx:columns> <mx:Array> <mx:DataGridColumn columnName="fName"
headerText="First Name" />
<mx:DataGridColumn columnName="lName"
headerText="Last Name" />
<mx:DataGridColumn columnName="location"
headerText="Location" />
</mx:Array> </mx:columns> </mx:DataGrid> </mx:Panel> <mx:Panel id="supPanel" title="Support Group"
width="{empPanel.width}">
<mx:DataGrid dragEnter="dataController.doDragEnter(event)"
dragDrop="dataController.doDragDrop(event)">
<mx:columns> <mx:Array> <mx:DataGridColumn columnName="fName"
headerText="First Name" />
<mx:DataGridColumn columnName="lName"
headerText="Last Name" />
<mx:DataGridColumn columnName="location"
headerText="Location" />
</mx:Array> </mx:columns> </mx:DataGrid> </mx:Panel> </mx:VBox> </mx:HBox> </mx:Application>
完成した「Employee.as」ファイルのコード
class Employee
{
    // プロパティ
    public var fName:String;
    public var lName:String;
    public var location:String;
    // コンストラクタ関数
    public function Employee()
    {}
// メソッド
   public function addEmpData
(fName:String,lName:String,location:String):Void
   {
       this.fName=fName;
       this.lName=lName;
       this.location=location;
   }
}
完成した「DataController.as」ファイルのコード
import mx.managers.DragManager;
import Employee;
class DataController
{
    // コンストラクタ関数
    public function DataController()
    {}
// メソッド
  public function addNewEmp(src:Object,dest:Object):Void
   {
// Employee オブジェクトの作成
   var tmpObj:Employee=new Employee();
// 新規データをオブジェクトのプロパティに追加
   tmpObj.addEmpData(src.fName,src.lName,src.location);
// employee オブジェクトをターゲットの dataProvider に追加
   dest.addItem(tmpObj);
   }
    public function doDragEnter(event):Void
   {
// ドロップ機能を有効化
   event.handled=true;
// action を copy に設定
   event.action = DragManager.COPY;
   }
     public function doDragDrop(event):Void
   {
   /*
event.dragSource.dataForFormat("items") は
ドラッグされたデータアイテムの配列を返します
*/
var items = event.dragSource.dataForFormat("items"); // 分かりやすくするために、ドロップターゲットのための変数を設定 var dest = event.target; // アイテムのターゲットの dataProvider にコピー addNewEmp(items[0],dest); } }
完成した「employees.xml」ファイルのコード
<allEmployees>
    <employee>
        <fName>
            Clare
        </fName>
        <lName>
            DuPre
        </lName>
        <location>
            Paris
        </location>
    </employee>
    <employee>
        <fName>
            David
        </fName>
        <lName>
            Green
        </lName>
        <location>
            San Francisco
        </location>
    </employee>
</allEmployees>
メモ
 ここに示すのは既製のデータファイルです。ご自分でこのファイルを作成する場合は、以下のデータを空のテキストファイルにコピーし、ファイルを「flex_tutorials」ディレクトリの中に「employees.xml」として保存してください。
完成した「locations.xml」ファイルのコード
<locations>
    <location>
        Paris
    </location>
    <location>
        Tokyo
    </location>
    <location>
        Cairo
    </location>
    <location>
        San Franscisco
    </location>
</locations>
メモ
 ここに示すのは既製のデータファイルです。ご自分でこのファイルを作成する場合は、以下のデータを空のテキストファイルにコピーし、ファイルを「flex_tutorials」ディレクトリの中に「locations.xml」として保存してください。

つぎのステップ

 是非、下記のチュートリアルも併せてご覧ください。

 このチュートリアルの内容にご関心をお持ちいただけた場合は、Flexにデフォルトで含まれているサンプルアプリケーションなども一度目を通すようにしてください。Flexの搭載機能をデモするサンプルが多数収録されています。

「FlexではじめるRIA開発」特集、絶賛公開中!

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Flex基礎講座連載記事一覧

もっと読む

この記事の著者

Robert Crooks(Robert Crooks)

Macromedia所属カリキュラム開発担当ディレクター。これまでに、『Fast Track to Macromedia Flex』を含む、インターネットアプリケーション開発関連の数々の教材を執筆。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

マクロメディア株式会社(マクロメディアカブシキガイシャ)

Macromediaは、先端的なソフトウェア会社であり、オープンで統合性のあるWeb開発プラットフォームを通じて、Webプロフェッショナルが魅力あるユーザー体験を提供するためのサービスを提供している。主な製品に「Flash MX 2004」「Dreamweaver MX 2004」「Director...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/109 2009/10/20 17:02

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング