2011-01-06 16 views
2

私はURLLoaderを使用してリモートサーバーから情報を取得しているフラッシュアプ​​リケーションを開発しています。私は製品IDに基づいて情報の要求を作成する機能を持っています。エラーが発生した場合、別のURLにフォールバックしますが、代替URLを作成するには、製品IDを知る必要があります。新しいURLを再生成できるように、どのURLLoaderが失敗したか(どの製品要求が失敗したか)を判断する最良の方法は何ですか?どのURLLoaderがプログラムで失敗したかをどのように判断するのですか?

私の機能は以下の通りです:

function loadData(productID:String):URLLoader { 
    var productURL:URLRequest = new URLRequest("/path/to/product/" + productID); 
    var dataLoader:URLLoader = new URLLoader(); 

    dataLoader.addEventListener(Event.COMPLETE, parseData); 
    dataLoader.addEventListener(IOErrorEvent.IO_ERROR, handleDataError); 
    dataLoader.load(productURL); 

    return dataLoader; 
} 

function handleDataError(e:IOErrorEvent) { 
    var productID:String = ???; 
    var altProductURL:URLRequest = new URLRequest("/alternate/path/to/product/" + productID); 
    var dataLoader:URLLoader = new URLLoader(); 

    dataLoader.load(altProductURL); 
} 

答えて

4

あなたは(新しい機能を説明)ローカル変数に自分のエラーハンドラをラップすることができますので、エラーイベントを受け取るメソッドにIDを渡すことができます。

私が間違っている場合
function loadData(productID:String):URLLoader { 
    var productURL:URLRequest = new URLRequest("/path/to/product/" + productID); 
    var dataLoader:URLLoader = new URLLoader(); 

    var errHandler:Function = function(event:IOErrorEvent):void { 
    handleDataError(event, productID); 
    }; 

    dataLoader.addEventListener(Event.COMPLETE, parseData); 
    dataLoader.addEventListener(IOErrorEvent.IO_ERROR, errHandler); 
    dataLoader.load(productURL); 

    return dataLoader; 
} 

function handleDataError(e:IOErrorEvent, productID:String) { 
    var altProductURL:URLRequest = new URLRequest("/alternate/path/to/product/" + productID); 
    var dataLoader:URLLoader = new URLLoader(); 

    dataLoader.load(altProductURL); 
} 
+0

これは本当にシンプルで、最小限のコードで優雅に質問に答えるため、これを選択しました。この長期的な使用が必要な場合や、複数のプロジェクト(複数のプロジェクトなど)で使用する場合は、おそらくJuanのソリューションを使用します。 – Steropes

+0

@Steropes、うまくいきました。私は同意します - Juanのソリューションは非常にエレガントで、フェールオーバー機能をうっかり隠しています。 – bedwyr

7

は、私を修正しますが、e.targetまたはe.currentTarget失敗はURLLoaderではないでしょうか?

+0

+1はとても正しいです。 – weltraumpirat

+0

はい。あなたのhandleDataError関数で、 "e.currentTarget"はローダーインスタンスに評価されます。そこから、使用したURLにアクセスしてIDをリバースエンジニアリングするだけです。 – Myk

+0

はい、e.targetとe.currentTargetは失敗したURLLoaderを取得しますが、どのURLLoaderであるかを判断するための情報を与えるurl属性はありません。私は、URLLoaderオブジェクトを他のデータ、つまりproductIDで参照するのに最適な方法を探しています。言い換えれば、無名のURLLoaderオブジェクトからproductIDを取得する方法で、URLLoaderオブジェクトをproductIDに結び付けるにはどうすればよいですか? – Steropes

2

エラーハンドラをクロージャにラップするか、ターゲットからIDを取得する代わりに、リトライメカニズムを隠すカスタムローダを書き込むことになるので、通常のローダのように使用することができます。

このような

何か(私はメモ帳でこれを書いたので、それはおそらくエラーを持っていますが、ちょうどあなたのアイデア...与えるために):あなたのロード機能で次に

public class ProductDataLoader extends EventDispatcher { 

    private var _paths:Array; 
    private var _id:String; 
    private var _state:int; 

    private var _loader:URLLoader; 
    private var _data:Object; 

    public function get data():Object { 
     return _data; 
    } 

    public function ProductDataLoader(id:String) { 
     _paths = [ 
      "/path/to/product/", 
      "/alternate/path/to/product/" 
     ]; 
     _id = id; 
     _state = -1; 

     _loader = new URLLoader(); 
     _loader.addEventListener(Event.COMPLETE, handleComplete); 
     _loader.addEventListener(IOErrorEvent.IO_ERROR, handleError); 

    } 

    public function load():void { 
     if(hasNextPath()) { 
      _loader.load(new URLRequest(getNextPath())); 
     } else { 
      // here, we ran out of paths to try 
      // you shouldn't get here unless you call loadProduct() 
        //  more than once. 
      // you should probably throw an error here, but that's up to 
     } 

    } 

    private function hasNextPath():Boolean { 
     return _state < _paths.length - 1; 
    } 

    private function getNextPath():String { 
     _state++; 
     return _paths[_state] + _id;  
    } 

    private function handleComplete(e:Event):void { 
     // redispatch the complete event 
     _data = _loader.data; 
     dispatchEvent(e); 
    } 

    private function handleError(e:Event):void { 
     if(hasNextPath()) { 
      loadProduct(); 
     } else { 
      // we tried all paths without success 
      // so we just redispatch the error event 
      dispatchEvent(e); 
     } 
    } 

} 

function loadData(productID:String):URLLoader { 

    var productLoader:ProductDataLoader = new ProductDataLoader(productId); 
    dataLoader.addEventListener(Event.COMPLETE, parseData); 
    dataLoader.addEventListener(IOErrorEvent.IO_ERROR, handleDataError); 
    dataLoader.load(); 
} 
+0

+1:私は閉鎖のアイデアよりもこれが好きです:) – bedwyr

+0

@ bedwyr。ありがとう。このアプローチについて私が気に入っているのは、呼び出し元からメカニズムが隠されているため、呼び出しコードは単純なままです。また、より堅牢なエラー処理を追加したい場合(ローダーが一貫性のある状態になっているかどうか、読み込み中に再入力しないなど)、「クライアント」コードを乱雑にすることなく簡単に行うことができます。このローダーをほぼ正規のローダーとして扱うことができます。 –

+0

bedwyrのコードよりも複雑ですが、このソリューションはより堅牢で、私のアプリケーションを将来的に証明し、必要に応じて簡単にコードを再利用できるようにします。私はbedwyrのソリューションをこの1つで選んだのは、一度しか使われないシンプルなソリューションが必要だったためで、コードの可読性を堅牢性よりも選んだからです。 – Steropes

関連する問題