JAVAC.JP
HOSHI TETSUYA 星鉄矢
2005/07/25
hossy@javac.jp
http://www.javac.jp
Google
WWW を検索 WWW.JAVAC.JP を検索

4-2 XML通信とDataStorageの連携例

以下が、XMLをロードしdataStorageに格納し、必要に応じて出力するサンプルである。
簡便のために、ComboBox,TextInputコンポーネントを利用しているが、これらのコンポーネントに関しては、ここでは深く言及しない。
example
ソースは5つのASファイルに分かれる。
タイムラインはmain.as
クラスファイルはExXML.as,UserListControl.as,UserListClass.as,UserListDataStorage.asである。
リンケージuserlistにUserListClassをレジスタークラスし、タイムラインにuserlistmovieclipのインスタンス名で配置している。
main.as
---
var control:UserListControl=new UserListControl(this.userlistmovieclip);
stop();
ExXMLクラスはXMLクラスを継承・拡張したものです。
ignoreWhiteをtrueに設定することで、XML内のタブ・キャリッジリターンを無効と認識させることができます。これを怠ると、予期しないパースをFlashPlayerが行うことがあります。
また、このクラスではonLoadが呼び出された際にsetCallBackメソッドで登録したメソッドをコールバックさせるようにしています。これは次ページで紹介するように、EventDispatcherを用いてonLoadコールバックを処理することで、また別の記述を可能にします。
XML通信は非同期に行われます。つまり、myXml.load(address);を呼び出した後、FlashPlayerはロード完了を待たずに処理を継続し、ロードの完了は別スレッドが監視し、完了後、onLoadメソッドが呼び出されることになります。
Flashにおいては非同期通信が基本となります。同期的に扱いたい場合は、各々のコールバックが起こるまで、処理の進行を待たせる仕組みを加える必要があります。
ExXML.as
---
class ExXML extends XML{
    private var ignoreWhite=true
    private var method:String;
    private var ref:Object;

    function ExXML(){
    }

    public function setCallBack(method:String,ref:Object):Void{
        this.method=method;
        this.ref=ref;
    }

    function onLoad():Void{
        ref[method]();
    }
}
UserListControlクラスは、DataStorageとView(UserListClass)をコネクトする、また、XML通信を行う役割を担います。
XML通信を行い、ロード完了後、適宜パーシングを行い、ComboBoxにアイテムを追加します。また、ComboBoxに変更があった際は、TextInput群に該当データを差し替えます。
UserListControl.as
---
class UserListControl{
    private var dataStorage:UserListDataStorage;
    private var mainMc:MovieClip;
    private var ex:ExXML;

    function UserListControl(path:MovieClip){
        mainMc=path;
        dataStorage=new UserListDataStorage();
        loadUserList("GetUsersInfo.cgi");
    }

    private function loadUserList(address:String):Void{
        ex=new ExXML();
        ex.setCallBack("onLoadXML",this);
        ex.load(address);
    }

    public function onLoadXML():Void{
        var arr:Array=ex.firstChild.childNodes;
        for(var i:Number=0;i<arr.length;i++){
            var x:XMLNode=XMLNode(arr[i]);
            if(x.nodeName=="user"){
                var o:Object=x.attributes;
                var index:Number=dataStorage.addUser(o);
                var name:String=dataStorage.getName(index);
                mainMc.addItem(String(index),name);
            }else{
                trace("XMLNode is invalid form.");
            }
        }
        mainMc.setListBoxHandler("onChangeListBox",this);
    }

    public function onChangeListBox(eventObj:Object):Void{
        var index:Number=Number(eventObj.index);
        mainMc.setIdText(dataStorage.getId(index));
        mainMc.setNameText(dataStorage.getName(index));
        mainMc.setAgeText(dataStorage.getAge(index));
        mainMc.setSexText(dataStorage.getSex(index));
        mainMc.setOccupationText(dataStorage.getOccupation(index));
    }
}
UserListDataStorageクラスはXMLから読み込んだデータを保持します。UserListControlクラスで適宜パースされたデータが追加され、必要に応じて該当indexを基にデータを吐き出します。
UserListDataStorage.as
---
class UserListDataStorage{
    private var userList:Array;

    function UserListDataStorage(){
        reset();
    }

    public function reset():Void{
        userList=new Array();
    }

    public function getLength():Number{
        return userList.length;
    }

    public function addUser(dataObj:Object):Number{
        userList.push(dataObj);
        var index:Number=getLength()-1;
        return index;
    }

    public function getId(index:Number):String{
        return String(userList[index].id);
    }

    public function getName(index:Number):String{
        return String(userList[index].name);
    }

    public function getAge(index:Number):String{
        return String(userList[index].age);
    }

    public function getSex(index:Number):String{
        return String(userList[index].sex);
    }

    public function getOccupation(index:Number):String{
        return String(userList[index].occupation);
    }
}
UserListClassクラスはムービークリップです。
メンバとして、ComboBoxのlistboxとTextInput群を持ちます。
コンポーネントComboBoxとTextInputに関して、詳細な説明は省きますが、コンポーネントを用いることでアクセシブリティを簡単に高めることができます。
UserListClass.as
---
import mx.events.EventDispatcher;
import mx.controls.TextInput;
import mx.controls.ComboBox;

class UserListClass extends MovieClip{
    var listbox:ComboBox;
    var idfield:TextInput;
    var namefield:TextInput;
    var agefield:TextInput;
    var sexfield:TextInput;
    var occupationfield:TextInput;
    var listBoxListener:Object;

    function UserListClass(){
    }

    function addItem(index:String,name:String):Void{
        listbox.addItem(name,index);
    }

    function setIdText(id:String):Void{
        idfield.text=id;
    }

    function setNameText(name:String):Void{
        namefield.text=name;
    }

    function setAgeText(age:String):Void{
        agefield.text=age;
    }

    function setSexText(sex:String):Void{
        sexfield.text=sex;
    }

    function setOccupationText(occupation:String):Void{
        occupationfield.text=occupation;
    }

    function setListBoxHandler(method:String,ref:Object):Void{
        listBoxListener=new Object();
        EventDispatcher.initialize(listBoxListener);
        listBoxListener.change=function(eventObj:Object){
            var lo:Object=new Object();
            lo.target=ref;
            lo.type=method;
            lo.index=eventObj.target.value;
            this.dispatchEvent(lo);
        }
        listBoxListener.addEventListener(method,ref);
        listbox.addEventListener("change",listBoxListener);
    }
}




BACKTOPNEXT




All Contents Copyright (C) 2005 HOSHI Tetsuya
Home