Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache flex 将web服务结果与Flex中的请求匹配_Apache Flex_Web Services_Actionscript_Asynchronous - Fatal编程技术网

Apache flex 将web服务结果与Flex中的请求匹配

Apache flex 将web服务结果与Flex中的请求匹配,apache-flex,web-services,actionscript,asynchronous,Apache Flex,Web Services,Actionscript,Asynchronous,在我回答这个问题之前,先了解一点背景知识: 我有一个手风琴控件,它加载了一组网格,每个网格都加载了一组东西。我正在使用自动生成的web服务代理来检索这些列表。我希望用户能够更改手风琴中选定的子项,而不必等待web服务响应。我最初对所有请求使用同一个代理实例,并按请求发出的顺序跟踪请求,但问题是较短的数组从服务器返回的速度更快,因此请求发出的顺序变得无关紧要 在处理代理结果事件时,我找不到一种明显的方法来确定原始请求,因此我最终得到的是一个函数,该函数处理accordion上的更改事件,实例化一个

在我回答这个问题之前,先了解一点背景知识:

我有一个手风琴控件,它加载了一组网格,每个网格都加载了一组东西。我正在使用自动生成的web服务代理来检索这些列表。我希望用户能够更改手风琴中选定的子项,而不必等待web服务响应。我最初对所有请求使用同一个代理实例,并按请求发出的顺序跟踪请求,但问题是较短的数组从服务器返回的速度更快,因此请求发出的顺序变得无关紧要

在处理代理结果事件时,我找不到一种明显的方法来确定原始请求,因此我最终得到的是一个函数,该函数处理accordion上的更改事件,实例化一个新的webservice代理,将其放入具有所选子级索引的哈希表中,然后添加一个闭包作为事件处理程序。i、 e.有点像这样:

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的唯一方法是在方法调用最初返回AsyncToken的时候。

好的,我想我理解:由于请求是在选择时发出的,并且您通过本地代理调用,并且响应是随机返回的,所以您无法区分哪个响应映射到哪个UI元素。有道理

嗯,在不知道代理对象是什么类型的“东西”的情况下很难说,但是假设它是一种具体的东西,可以适当地映射到UI对象——比如说,ListoWidgets到DataGrid——那么不管怎样,最好让每个网格映射到它自己的ListoWidgets代理实例。在这种情况下,当您实例化一个代理时,您可以将其结果应该填充的网格索引传递给它(与上面的操作类似,但目的是将索引作为公共成员存储在代理对象上,而不是存储在单独的对象中)。然后,由于每个代理的结果事件处理程序都应该通过事件的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);
}
如果使用数据绑定,则编码模型会简单一些,在这种情况下,如果代理类或其结果集合标记为可绑定,则可以执行类似的操作:

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


。。。让事情“正常工作”(因为每个代理的实例都是唯一的)。这有意义吗?希望我正确地理解了这个问题

我恐怕不能完全理解您要做的所有事情,但如果我理解正确,您将发出许多请求并异步返回多个响应,并且您正在尝试将响应与请求相匹配

我在过去也做过类似的事情,我在文本字段中调用了keyup上的webservice来执行“键入时搜索”之类的功能,但这意味着我总是只关心最后一个请求的响应。因此,我将服务更改为也获取时间戳的参数(精确到毫秒),并将其与响应的其余部分一起返回。然后,我可以在响应中查找最新的时间戳,或者在flex端,跟踪最后一个请求的时间戳并查找特定的响应

您也可以使用任何类型的UUID或任何独特的东西来实现这一点。在服务端需要做更多的工作,但它的扩展性很好,并且易于理解

您可能会看到的另一件事,我很抱歉我自己没有对此进行更多的研究,就是在debug中查看生成的请求和响应对象。您可能会在这些对象中找到一些辅助信息,以便进行匹配。但我担心这在很大程度上取决于你打电话和收到回复的方式


希望我对这个问题理解得足够好。

不确定这是否有帮助,但我有一个类似的情况,我有一个远程对象,我调用了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";
}
public function resultHandler(event:ResultEvent):void {
    if( event.token.operation == "list" ) {
      // do something
    }   else if( event.token.operation == "update" ) {
    // do something
    }   
    // etc...
然后,
resultHandler
如下所示:

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";
}
public function resultHandler(event:ResultEvent):void {
    if( event.token.operation == "list" ) {
      // do something
    }   else if( event.token.operation == "update" ) {
    // do something
    }   
    // etc...
操作
是一个动态属性,不是AsyncToken的成员,因此您可以随意调用它。
有一篇食谱文章对此进行了描述:

这是有道理的,是的,但我不认为这是一个不需要重新构造代理类(反正是自动生成的)就可以轻松使用的解决方案。此外,代理被许多其他控件使用,并且有许多其他方法。也就是说,它不只是得到东西,它也得到了FOS、Bar、熊、犀牛……我确实考虑过这样的事情,但是我宁愿不必改变Web服务本身(它是一个.NET项目,我想暂时离开它——其他的东西依赖它)。这是很好的,并且应该按照海报所要求的去做。我希望我能喜欢这个答案。这正是我在回答的最后一段中所想的。我确实查看了getThings方法返回的AsyncToken,但它只有在我