0

アセット フォルダーから xml ファイルを読み込もうとしています。

私はこの関数を書きました:

        public static function loadXML(i_fileURL:String):XML // i want to return the actual loaded xml here
    {
        var xml:XML;
        var ldr:URLLoader = new URLLoader();
        var request:URLRequest = new URLRequest(i_fileURL);
         ldr.addEventListener(Event.COMPLETE, onXMLLoad);
         ldr.load(request);
                     //how can i return the loaded xml?
    }

        public static function onXMLLoad(e:Event):void
    {
        var ldr:URLLoader = URLLoader(e.target);
        var myxml:XML = new XML(ldr.data);
        trace(myxml.toXMLString());
                   //how can i return myxml to loadXML function?

    }

これを行う別の方法はありますか?

ありがとうございました!

4

3 に答える 3

1

promise や future のようなことを行うことができます。空の XML を返し、呼び出しが返されたときに実際の XML を入力します。Flex を使用しているため、データ バインディングにアクセスできます。これにより、このアプローチがうまく機能するはずです。

これには静的メソッドを使用するべきではなく、 onXMLLoad メンバーを公開する理由がないことに注意してください。更新されたコードは次のようになります。

パッケージサービス {
    パブリック クラス XMLLoader {
        // この変数が存在するということは、
        //呼び出しを行うたびにクラスの新しいインスタンスを作成します。
        保護された var future:XML;
        保護された var _url:文字列;
        public function loadXML(url:String):XML {
            _url = URL;
            var request:URLRequest = 新しい URLRequest(url);
            var loader:URLLoader = 新しい URLLoader();
            loader.addEventListener(Event.Complete, onLoad);
            loader.addEventListener(IoErrorEvent.IO_Error, onFail);
            loader.addEventListener(SecurityErrorEvent.Security_Error, onFail);
            未来 = ;
            未来を返す;
        }
        保護された関数 onLoad(e:Event):void {
            var loader:URLLoader = URLLoader としての e.currentTarget;
            var data:XML = XML としての loader.data;
            if (データ) {
               // データが必要なため、元のルート ノードが失われます
               //返された将来のオブジェクトで起動するバインディング。
               future.setChildren(data.children());
            }
        }
        保護された関数 onFail(e:Event):void {
            // Security と IOerrors の両方に text プロパティがありますが、
            //両方を同じものにキャストすることはできません。
            trace('ロードに失敗しました', _url, e[テキスト]);
        }
    }
}

このメソッドで注意すべきことの 1 つは、データが更新されるまでインスタンスへの参照を維持する必要があることです。そうしないと、フューチャにデータが入力される前にガベージ コレクションが実行される可能性があります。そのため、取得したデータを運ぶカスタム イベントをインスタンスにディスパッチさせる従来のアプローチに従う方がよいでしょう。その例が必要な場合は、返信してください。例を提供できます。

于 2013-03-03T19:27:48.173 に答える
0

できません。xml ロード リクエストは非同期であるためです。あなたが電話したときloadXMLonXMLLoadまだ到着していません。そのような作業は不可能な非同期リターンです。確かに関数処理whileループを使って待つことはできますが、この方法は良くありません。CPU リソースをフルに使用するには、やり過ぎです。関数で次の処理を行う必要がありonXMLLoadます。一番適当です。または xml 変数をグローバルとして宣言し、xml が null でない場合に操作を続行する方法としてENTER_FRAMEorを使用します。TimerEvent

于 2013-03-03T12:25:23.073 に答える
0

URLLoader は非同期であるため、静的ローダー関数を作成するのは安全ではありません。複数回の呼び出し中に返されたデータを混同しやすいからです。各 URL に属する完成したデータを追跡するために、URL のベクトルを使用して目的を達成しようとしてもEvent.OPEN、非同期性は先着順で機能するため、そうはなりません。ファイル URL と返されたデータの永続的なアラインメントを持つことが可能です。

XMLLoadercustom を使用するクラスのインスタンスを作成することをお勧めしますXMLLoaderEvent。これは、xml データと関連するファイル URL の両方を返します。次のコードはテストされていませんが、タイプミスの可能性は別として、意図したとおりに動作するはずです。

使用事例

var xmlLoader:XMLLoader = new XMLLoader();
xmlLoader.addEventListener(XMLLoaderEvent.COMPLETE, xmlLoadCompleteEventHandler);
xmlLoader.load("myXMLFile.xml");

function xmlLoadCompleteEventHandler(event:XMLLoaderEvent):void
{
    xmlLoader.removeEventListener(XMLLoaderEvent.COMPLETE, xmlLoadCompleteEventHandler);

    trace(event.type, event.fileURL, event.xml);
}

XMLLoader.as

package
{
    //Imports
    import flash.events.EventDispatcher;
    import flash.events.Event;
    import flash.net.URLLoader;
    import flash.net.URLRequest;

    //Class
    public class XMLLoader extends EventDispatcher
    {
        //Properties
        private var loader:URLLoader;
        private var fileURL:String;

        //Constructor
        public function XMLLoader():void
        {
            loader = new URLLoader();
            loader.addEventListener(Event.COMPLETE, loadCompleteEventHandler);
        }

        //Load
        public function load(fileURL:String):void
        {
            this.fileURL = fileURL;

            loader.load(new URLRequest(fileURL));            
        }

        //Load Complete Event Hanlder
        private function loadCompleteEventHandler(event:Event):void
        {
            loader.removeEventListener(Event.COMPLETE, loadCompleteEventHandler);

            dispatchEvent(new XMLLoaderEvent(XMLLoaderEvent.COMPLETE, fileURL, XML(loader.data)));
        }
    }
}

XMLLoaderEvent.as

package
{
    //Imports
    import flash.events.Event;

    //Class
    public class XMLLoaderEvent extends Event
    {
        //Constants
        public static const COMPLETE:String = "complete";

        //Properties
        public var xml:XML;
        public var fileURL:String;

        //Constructor
        public function XMLLoaderEvent(type:String, fileURL:String = null, xml:XML = null) 
        {
            super(type);

            this.xml = xml;
            this.fileURL = fileURL;
        }

        //Clone
        public override function clone():Event
        {
            return new XMLLoaderEvent(type, fileURL, xml);
        }

        //To String
        public override function toString():String
        {
            return formatToString("XMLLoaderEvent", "type", "fileURL", "xml");
        }
    }
}
于 2013-03-04T01:30:09.287 に答える