更新日期:2010.7.24
1.本例目的 异步远程调用与Command标签
command与DynamicCommand的使用方法及区别
2.远程调用 FLEX的远程调用都是异步的,不通过Parsley框架进行远程调用,详见《
FLEX异步调用》
或ParsleyExample5项目中的TestAsyncToken.mxml。
3.利用Command标签远程调用 Command标签
可以让框架去管理异步命令的执行
。其过程如下
3.1从界面派发LoginEvent事件,调用远程对象界面TestCommandMeta.mxml部分代码如下:
注:
CommandMetaConfig为配置文件
view:LoginPanel为自定义视图组件
自定义视图组件LoginPanel.mxml部分代码如下
[Inject]
[Bindable]
public var loginPM:LoginPM; //视图model类
private function login():void {
loginPM.login();
}
//输入登录名
text="{loginPM.password}" displayAsPassword="true"/> //输入密码
//回显信息
3.2视图model类LoginPM.as
视图model实现了视图显示代码与逻辑代码的分离。
[Bindable]
public var username : String="李家里"; //与登录名绑定
[Bindable]
public var password : String="12345"; //与登录密码绑定
[Inject]
[Bindable]
public var model:UserModel; //测试用的,model.xm回显在label组件上
[MessageDispatcher]
public var sendMessage:Function; //派发事件函数
public function login() : void{
sendMessage(new LoginEvent(username,password)); //派发一个事件
}
//当远程调用对象返回AsyncToken后,parsley自动调用CommandResult标签,进行处理
[CommandResult(selector="login")]
public function onLoginResult(m:UserModel,event:LoginEvent):void
{
//注意,model引用的对象是parsley托管的,如果写成model=m,并不能替换parsley托管的对象
model.xm=m.xm; //测试回显
username =event.password; //测试回显
}
[CommandError( selector="login")]
public function onLoginError(fault:FaultEvent,event:LoginEvent):void
{
username =fault.message.toString(); //错误处理
}
说明
1.对于AsyncToken的处理,CommandResult标签可以在多处添加,parsley将一一进行处理,但是并不保证执行顺序。
2.CommandResult,parsley提供了两种写法
[CommandResult(selector="login")]
public function onLoginResult(model:UserModel,event:LoginEvent):void : void {
上例中,model实例由远程调用返回,与触发动作的原始消息一起传给结果处理器。第二个参数是可选的,如果你忽略它,你必须用标签描述消息类型,以进行精确匹配:
[CommandResult(type="com.foo.events.LoginEvent" selector="login")]
public function handleResult (
model:UserMode) : void {
但是,经过本人测试,第二种写法不可行。不知道为什么?
3.3LoginEvent事件
public class LoginEvent extends Event
{
private static const LOGIN:String = "login";
private var _username : String;
private var _password : String;
public function LoginEvent(username:String,password:String)
{
this._username=username;
this._password=password;
super(LOGIN, false, false);
}
}
3.4 登录业务处理
登录业务处理,一般放在一个单独的类LoginAction.as中
ILoginService接口声明了远程调用必须实现的方法,将通过parsley注入到这里,这样注入的对象
既可以是RemoteObject,也可以是Mock对象。
public class LoginAction
{
//通过接口注入远程调用对象,
既可以是RemoteObject,也可以是Mock对象
[Inject]
public var loginService:ILoginService;
[Inject]
public var model:UserModel; //测试用
[Command(selector="login")]
public function execute(event:LoginEvent):AsyncToken
{
return loginService.login(event.username,event.password);
}
[CommandResult(selector="login")]
public function loginResult(m:UserModel,event:LoginEvent):void
{
model.xm="王辉";//此处为测试两个CommandResult的执行顺序
}
}
说明:
1。LoginAction与LoginPM类中都有
[CommandResult(selector="login")],
二个类都对异步调用结果进行处理,但并不保证执行的顺序。
3.5模拟远程对象
这里给出了模拟远程调用的服务类
public class LoginServiceMock implements ILoginService {
private var user:UserModel;
private var mockServiceUtil:MockServiceUtil = new MockServiceUtil();
public function LoginServiceMock() {
}
public function login(username:String, password:String):AsyncToken {
var model1:UserModel;
model1 = new UserModel();
model1.xh="995312";
model1.xm="王一冰";
return mockServiceUtil.createToken( model1 );
}
}
3.6配置文件
4.DynamicCommand
我们一般用一个完整的命令对象对结果进行处理。这个对象仅是单个方法,用于执行命令。
parsley为每个匹配消息创建一个新的命令实例。多个命令对象可以并发执行,并且不进行任何交互。
对于Command层,方法至少有三个:execute,result和fault,代码如下:
public class SaveUserCommand {
[Inject]
public var service:RemoteObject;
public function execute (event:UserEvent) : AsyncToken {
return service.saveUser(event.user);
}
public function result (user:User) : void {
// do something with the result
}
public function error (fault:Fault) : void {
// do something with the result
}
}
在配置类中定义[DynamicCommand]标签:
说明:
1.这三个函数执行过程为:首先execute函数被调用,execute调用service类,Service类返回AsyncToken ;其次,parsley框架根据配置文件,自动调用result或fault函数,对AsyncToken 中返回的数据进行处理;
程序举例如下
4.1配置文件
4.2 界面、PM类、LoginEvent
同上
4.3登录业务处理
这里采用动态对象方法,实现类必须实现三个方法,代码如下
LoginCommand.as
public class LoginCommand {
[Inject]
public var loginService:ILoginService; //注入远程调用对象
[Inject]
public var model:UserModel;//注入parsley托管的UserModel
public function execute( event:LoginEvent ):AsyncToken {
return loginService.login( event.username, event.password );
}
public function result ( model:UserModel ) : void {
model.xm="王辉";//此处为测试两个CommandResult的执行顺序
}
public function error (fault:Fault) : void {
}
}
说明
1.采用动态对象后,依然可以使用CommandResult标签,但是,parsley不保证执行的顺序。例如,在LoginPM里,以下代码依然能对登录事件的结果进行响应。
[CommandResult(selector="login")]
public function onLoginResult(m:UserModel,event:LoginEvent):void
{
//注意,model引用的对象是parsley托管的,如果写成model=m,并不能替换parsley托管的对象
model.xm=m.xm;
username =event.password;
}
2.动态对象都是短生命周期的,一个事件新创建一个处理对象。如果你想只使用一个实例,可如下设置
stateful="true"/>
由于项目比较大,代码只能给出关键部分,具体见项目parsleyExample5
参考文献
1.parsley学习指南5-消息.http://blog.chinaunix.net/u/21752/showart.php?id=2225195
阅读(2429) | 评论(1) | 转发(1) |