21.6.创建Cairngorm命令和事务代理类

21.6.1.问题
我需要创建一个从FrontController中调用的命令类和一个跟这个命令通信的事务代理类。
21.6.2.解决方案
创建一个实现了ICommand和mx.rpc.IResponder接口的类。你的事务代理类不需要扩展任何类,也不需要实现任何接口。它需要在构造函数中接收一个IResponder接口的实例,这样它就可以处理传递给它的IResponder实例的结果,或调用错误处理函数。这个IResponder实例就是调用事务逻辑的命令。
21.6.3.讨论
在最新版本的Cairngorm小型结构之前,command类实现com.adobe.cairngom.business.Responder类。在Cairngorm最新的版本(在写本书时是2.2.1)中,已经不推荐使用Responder类,而是像下面代码那样使用mx.rpc.IResponder接口。

Cairngorm的所有command类都实现了ICommand接口,这个接口中定义了一个这样形式的execute方法:
+展开
-ActionScript
function execute(event:CairngormEvent):void

下面是RecipeCommand类:
+展开
-ActionScript
package oreilly.cookbook.cairngorm.commands {
import com.adobe.cairngorm.commands.ICommand;
import com.adobe.cairngorm.control.CairngormEvent;
import mx.controls.Alert;
import mx.rpc.IResponder;
import mx.rpc.events.FaultEvent;
import oreilly.cookbook.cairngorm.business.BusinessDelegate;
import oreilly.cookbook.cairngorm.events.RecipeEvent;
import oreilly.cookbook.cairngorm.model.Model;
public class RecipeCommand implementsICommand, IResponder
{
/*当发送正常的CairngormEvent时,Cairngorm FrontController会调用command的这个execute方法。事件类型和command之间是一对一或多对一的关系,也就说一个command可以被多个事件或单个事件调用,但是一个CairngormEvent只触发一个command。Command必须处理特定操作需要的所有逻辑。下面的示例中的command的execute方法创建一个事务代理对象,并把它自己注册为处理服务调用结果或失败的IResponder:*/
public function execute(event:CairngormEvent):void{
if(event.type== RecipeEvent.GET_RECIPE){
var delegate:BusinessDelegate = new BusinessDelegate(this);
delegate.getRecipes(event.recipeKeywords);
}
}

如果服务器返回了正常的数据,事务代理会调用result方法。Command处理从服务器返回的结果,进行一些必要的操作,通常会设置模型中的值。在本文的例子中,模型的recipeArray被设置成返回的结果的值。因为这个程序的视图绑定到recipeArray上,recipeArray又标记为可绑定的,所以当recipeArray的值发生改变时,视图会同时更新。这样这个应用程序中的关系就很清晰;当更新或修改时,模型不需要做任何事情,视图也不需要知道服务器什么时候会返回结果以便更新显示。
+展开
-ActionScript
public function result(arr:ArrayCollection):void {
Model.getInstance().recipeArray= arr;
}
publicfunction fault(event:FaultEvent):void
{
Alert.show(event.message);
}
}
}

基于Cairngorm的应用程序中的事务代理类中有mx.rpc.IResponder类的引用,就是既能处理返回结果也能处理失败的command。这个代理使用ServiceLocator调用特定的服务,当服务返回时,代理又把结果传递给IResponder处理。
+展开
-ActionScript
package oreilly.cookbook.cairngorm.business {
import mx.rpc.IResponder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.RemoteObject;
public class BusinessDelegate {
private var responder:IResponder;
public function BusinessDelegate(responder:IResponder){
this.responder= responder;
}

这里这个由RecipeCommand 调用的方法收到了要传给服务器的一个数组。通过使用ServiceLocator,这个方法能调用正确的服务。服务器的响应或失败都会传递给创建了这个事务代理的command。同样,这个分离使得代码更有弹性,更易于维护。
+展开
-ActionScript
public function getRecipes(params:Array):void {
// we access the RemoteObject stored in the ServiceLocator by using the Cairngorm ServiceLocator singleton
// and passing a reference to the id of the RemoteObject that we wish to call
var service:RemoteObject = com.adobe.cairngorm.business.ServiceLocator.getInstance().getRemoteObject("recipeService");
var token:AsyncToken = service.send(params);
var responder:mx.rpc.Responder= new mx.rpc.Responder(getRecipeResult, getRecipeFault);
token.addResponder(responder);
}

当服务器返回结果时,responder,也就是command,会处理数据,并设置模型中的相应属性。

这个事务代理类的实例已经完成了它的工作,接下来它会被垃圾回收。
+展开
-ActionScript
private function getRecipeResult(event:ResultEvent):void {
responder.result(event.resultas ArrayCollection);
}
private function getRecipeFault(event:FaultEvent):void {
responder.fault(event);
}
}
}

加支付宝好友偷能量挖...


评论(0)网络
阅读(101)喜欢(0)flash/flex/fcs/AIR