3

質問に入る前に、少し (!) 背景を説明します。

グリッドの配列がロードされたアコーディオン コントロールがあり、それぞれが物事の配列で遅延ロードされます。これらのリストを取得するために、自動生成された Web サービス プロキシを使用しています。Web サービスの応答を待たずに、ユーザーがアコーディオンで選択した子を変更できるようにしたいと考えています。私は元々、すべてのリクエストに同じプロキシ インスタンスを使用し、リクエストを作成された順序で追跡していましたが、これの問題は、配列が短いほどサーバーからより迅速に返されるため、リクエストが作成された順序が無関係になることです。 .

プロキシ結果イベントを処理するときに元のリクエストを特定する明白な方法を見つけることができなかったので、最終的には、アコーディオンの変更イベントを処理し、新しい Web サービス プロキシをインスタンス化し、それをハッシュテーブルに押し込む関数になりました。選択した子のインデックスを作成し、クロージャーをイベント ハンドラーとして追加します。つまり、次のようなものです。

private proxyTable:Object = new Object();
private function PopulateThingGrid(index:Number):void
{
    var grid:ThingGrid = myAccordion.getChildAt(index) as ThingGrid;
    grid.things = ArrayCollection(proxyTable[index].getThings_lastResult);
}

private function SendThingRequest(index:int):void
{
    var grid:ThingGrid= myAccordion.getChildAt(index) as ThingGrid;
    if (grid.things.length == 0)
    {
        if (proxyTable[index] == null)
        {
            proxyTable[index] = new MyWebServiceProxy();
        }
        var proxy:MyWebServiceProxy= proxyTable[index];
        proxy.addgetThingsEventListener(function ():void { PopulateThingGrid(index); });

        var list:ThingList = thingLists.getItemAt(index) as ThingList;
        proxy.getThings("thinglist", list.ListID);
    }
}

private function myAccordion_Change(event:IndexChangedEvent):void
{
    SendThingRequest(event.newIndex);
}

(これを少し匿名化しようとしたので、何かを見落としているかもしれませんが、うまくいけばアイデアが得られます)

それで、質問に:プロキシの結果を、私が見逃している元のリクエストと一致させる簡単な方法はありますか?

そうでない場合、私が行ったことは合理的ですか?最終的に生成してからそれらを正しく破棄する可能性のあるプロキシ インスタンスの数について少し心配しています (それが必要になった場合)。

更新: 生成されたプロキシ コードが、mx.rpc.events.ResultEvent ではなく、flash.events.Event から ResultEvents をサブクラス化するため、問題が発生する可能性があると思います。なぜこれを行うのか完全にはわかりません.AsyncTokenにアクセスする唯一の方法は、メソッド呼び出しによって最初に返されたときです.

4

3 に答える 3

8

これが役立つかどうかはわかりませんが、同様の状況がありました.4つのCRUDメソッドを呼び出すRemoteObjectがありましたが、resultHandlerは1つだけでした. を使用してこれを解決しましたAsyncToken

私の RemoteObject 呼び出しは次のようになりました。

public function list() {
    var token:AsyncToken = myService.list();
    token.operation = "list";
}

public function update() {
    var token:AsyncToken = myService.update(selectedItem);
    token.operation = "update";
}

public function create() {
    var token:AsyncToken = myService.create(selectedItem);
    token.operation = "create";
}

public function delete() {
    var token:AsyncToken = myService.delete(selectedItem);
    token.operation = "delete";
}

次に、次のresultHandlerようになります。

public function resultHandler(event:ResultEvent):void {
    if( event.token.operation == "list" ) {
      // do something
    }   else if( event.token.operation == "update" ) {
    // do something
    }   
    // etc...

operationは動的プロパティであり、AsyncToken のメンバーではないため、好きなように呼び出すことができます。ここにそれを説明するクックブックの記事があります:

于 2009-01-22T15:26:00.170 に答える
1

あなたがやろうとしていることのすべてを完全に理解しているわけではありませんが、私が正しく理解していれば、多くのリクエストを作成し、複数の応答を非同期で取得しており、応答を要求と一致させようとしています。

私は過去に同様の問題に対してこれを行ったことがあります。テキストフィールドのキーアップでWebサービスを呼び出して、「入力時に検索」のような機能を実行していましたが、それが意味するのは、常に応答のみを気にするということでした最後のリクエスト。そのため、サービスを変更して、タイムスタンプのパラメーター (ミリ秒まで) を取得し、残りの応答と共にそれを返すようにしました。次に、応答またはフレックス側で最新のタイムスタンプを探し、最後の要求のタイムスタンプを追跡して、その特定の応答を探すことができます。

これは、任意の種類の UUID または一意のもので行うこともできます。サービス側でもう少し作業が必要ですが、スケーリングがよく、簡単に理解できます。

他に確認できることは、生成されたリクエスト オブジェクトとレスポンス オブジェクトをデバッグで調べることです。照合を行うために調べることができるこれらのオブジェクトで、いくつかの補助的な情報を見つけることができます。しかし、それはあなたがどのように電話をかけ、応答を受け取るかに大きく依存するのではないかと思います.

HTH と私が問題を十分に理解していることを願っています。

于 2009-01-22T14:31:20.153 に答える
1

わかりました。リクエストは選択時に行われ、ローカル プロキシを介して呼び出され、応答がランダムに返されるため、どの応答がどの UI 要素にマップされているかわかりません。理にかなっています。

うーん。プロキシ オブジェクトがどのような「もの」であるかを知らずに言うのは難しいですが、それが UI オブジェクトに適切にマップされる具体的なものであると仮定すると (ListOfWidgets を DataGrid にマップするなど)、おそらく各グリッド マップを作成する方がよいでしょう。とにかく、ListOfWidgets プロキシの独自のインスタンスに。その場合、プロキシをインスタンス化するときに、その結​​果が入力されるグリッドのインデックスを渡すことができます (上記で行っていることと同様ですが、インデックスをプロキシ オブジェクトのパブリック メンバーとして格納する意図があります。別のオブジェクトではなく)。次に、各プロキシの結果イベント ハンドラは、イベントのターゲット プロパティを介してプロキシへのアクセスを提供する必要があるため、プロキシのターゲット インデックス (たとえば、event.target.index) を取得して、適切なグリッドに入力できます。

public class MyProxy
{
    public var targetIndex:uint;

    public function MyProxy()
    {
        // ...
    }
}

private function handleSelection():void
{
    var proxy:MyProxy = new MyProxy();
    proxy.addGetThingsEventListener(Event.YOUR_RESULT_EVENT, yourHandler); 
    proxy.targetIndex = 1;
}

private function yourHandler(event:Event):void
{
    fillGridWithResults(event.target.targetIndex);
}

データ バインディングを使用している場合、コーディング モデルは少し単純になります。この場合、プロキシ クラスまたはその結果コレクションのいずれかが Bindable とマークされていれば、次のようなことを行うことができます。

<mx:DataGrid dataProvider="{proxy.results}" />

...そして、物事が「うまくいく」ようにします(各プロキシのインスタンスは一意であるため)。これは理にかなっていますか?うまくいけば、問題を正しく理解できました。;)

于 2009-01-22T14:19:42.923 に答える