Соответствие результатов веб-службы запросам во Flex - PullRequest
3 голосов
/ 22 января 2009

Немного (!) Фона, прежде чем я смогу добраться до вопроса:

У меня есть гармошка, загруженная массивом сеток, каждая из которых лениво загружена массивами вещей. Я использую автоматически сгенерированный прокси веб-службы для получения этих списков. Я бы хотел, чтобы пользователь мог изменить выбранного ребенка в аккордеоне, не дожидаясь ответа веб-службы. Первоначально я использовал один и тот же экземпляр прокси-сервера для всех запросов и отслеживания запросов в том порядке, в котором они были сделаны, но проблема в том, что более короткие массивы возвращаются с сервера быстрее, поэтому порядок выполнения запросов становится неактуальным .

Я не смог найти очевидный способ определить исходный запрос при обработке результирующего события прокси, так что в итоге я получил функцию, которая обрабатывает событие change на гармошке, создает новый прокси-сервер веб-службы и помещает его в hashtable с индексом выбранного дочернего элемента, а затем добавляет замыкание в качестве обработчика события. то есть что-то вроде этого:

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);
}

(Я пытался немного анонимизировать, так что, возможно, я что-то упустил, но, надеюсь, вы поняли)

Итак, на вопрос (ы): есть ли более простой способ сопоставить результаты прокси с исходными запросами, которые я просто пропускаю?

Если нет, то что я сделал разумно? Меня немного беспокоит количество прокси-экземпляров, которые я мог бы в конечном итоге генерировать, а затем корректно их утилизировать (когда это становится необходимым) - есть ли какие-либо подводные камни, о которых я мог не знать?

Обновление: Я думаю, что проблема может возникнуть, потому что сгенерированный прокси-код подклассов ResultEvents из flash.events.Event, а не mx.rpc.events.ResultEvent. Я не совсем уверен, почему он это делает - единственный способ получить доступ к AsyncToken - это когда он изначально возвращается вызовом метода.

Ответы [ 3 ]

8 голосов
/ 22 января 2009

Не уверен, поможет ли это, но у меня была похожая ситуация, когда у меня был RemoteObject, для которого я вызываю 4 метода CRUD, но только один resultHandler. Я решил это с помощью 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, поэтому вы можете называть его как угодно. Здесь есть статья о Поваренной книге, описывающая это здесь :

1 голос
/ 22 января 2009

Боюсь, я не до конца понимаю все, что вы пытаетесь сделать, но если я правильно понимаю, вы делаете много запросов и получаете несколько ответов асинхронно, и вы пытаетесь сопоставить ответ с запрос.

В прошлом я делал это для решения аналогичной проблемы, я вызывал веб-сервис по keyup в текстовом поле для выполнения функции поиска по мере ввода текста, но это означало, что я всегда заботился только о ответ на последний запрос. Поэтому я изменил службу так, чтобы она также принимала параметр метки времени (вплоть до миллисекунды) и возвращала его вместе с остальной частью ответа. Затем я мог бы искать последнюю отметку времени в ответах или на гибкой стороне, отслеживать отметку времени последнего запроса и искать этот конкретный ответ.

Вы также можете сделать это с любым UUID или чем-то уникальным. С сервисной стороны требуется немного больше работы, но она хорошо масштабируется и легко понятна.

Еще одна вещь, на которую вы, возможно, могли бы обратить внимание, и я прошу прощения за то, что я сам больше не исследую это, - это при отладке посмотреть на генерируемые объекты запроса и ответа. Вы можете найти некоторую вспомогательную информацию с теми объектами, на которые вы могли бы взглянуть, чтобы сделать сопоставление. Но я боюсь, что это будет сильно зависеть от того, как именно вы звоните и получаете ответ.

HTH и надеюсь, я понял проблему достаточно хорошо.

1 голос
/ 22 января 2009

Хорошо, я думаю, что понимаю: поскольку запросы выполняются во время выбора, и вы звоните через локальный прокси-сервер, а ответы возвращаются случайным образом, вы не можете сказать, какие ответы отображаются на какой элемент пользовательского интерфейса. , Имеет смысл.

Хм. Трудно сказать, не зная, что это за «объект» вашего прокси-объекта, но если предположить, что это что-то конкретное, которое соответствующим образом отображается на объект пользовательского интерфейса - скажем, ListOfWidgets на DataGrid - тогда, вероятно, лучше иметь каждую карту сетки в любом случае, для своего собственного экземпляра прокси ListOfWidgets. В этом случае, когда вы создаете экземпляр прокси, вы можете передать ему индекс сетки, которую должны заполнить его результаты (аналогично тому, что вы делаете выше, но с намерением сохранить индекс как открытый член для объекта прокси, в отличие от отдельного объекта). Затем, поскольку обработчик события-результата каждого прокси-сервера должен предоставлять вам доступ к прокси-серверу через свойство target события, вы можете получить целевой индекс прокси-сервера (например, 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}" />

... и что-то "просто работает" (поскольку экземпляр каждого прокси будет уникальным). Имеет ли это смысл? Надеюсь, я правильно понял проблему. ;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...