Flex 4.1 + BlazeDS框架 + Cairngorm框架(Demo实例)
Cairngorm的各个部分:
Cairngorm的工作流程大体是这样:
客户端界面由View组成的。View使用Flex的binding(绑定)来显示ModelLocator中包含的数据。View根据诸如鼠标点击,按钮按下以及拖拽之类的用户动作产生Event。这些Event被FrontController“广播”并“监听”,FrontController会将Event映射到Command。Command包括业务逻辑,创建所需的Delegate,处理Delegate的响应,以及更新存储在ModelLocator中的数据。由于View是绑定到ModelLocator中的数据上的,所以当ModelLocator中的数据改变的时候View也会自动更新。Delegate调用Service并且将结果提交给Command,这一步是可选的,但是推荐这么做。Service调用远程数据然后将结果提交给Delegate。 Delegate的最简单的形式就是一个中间人的角色。如果一个Command需要调用webservice来获得一些数据,它将创建一个Delegate来完成这个调用。一个Command创建一个Delegate,Delegate调用一个指定的dataService,Service返回结果给Delegate,Delegate返回结果给Command。 Delegate并不是100%必需的,但是当涉及测试&程序环境的时候它们很有帮助。相对于在Command代码中使用查找替换改变所有的引用来测试,将一个Delegate重映射到一个测试Service更为简单。 下面说我的Demo:完成用户登录在后台进行验证合法性,并反馈给前台。
package net.dreamhui.java; public class LoginUser { public UserVO currentUser; private String uName; private String pWord; // Flex端要调用的服务 public UserVO login(UserVO par_user) { uName = par_user.userName; pWord = par_user.passWord; if (uName.equalsIgnoreCase("mazhi") && pWord.equalsIgnoreCase("wwh")) { return par_user; } else { return null; } } } package net.dreamhui.java; public class UserVO { public String userName; public String passWord; public UserVO() { } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } } 对remote-config.xml文件进行配置,加入如下的代码: <destination id="loginUser"> <properties> <source>net.dreamhui.java.LoginUser</source> </properties> </destination>在flashbuilder中新建CairngormDemo的Flex项目并组织目录,如下所示: 各个文件的源代码如下: CairngormDemo.mxml文件源码如下: <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:business="net.dreamhui.business.*" xmlns:control="net.dreamhui.control.*" xmlns:view="net.dreamhui.view.*" creationComplete="creationComplete()"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; import net.dreamhui.model.UserModelLocator; protected function creationComplete():void { // UserModelLocator存储程序中的所有值对象 UserModelLocator.getInstance().addEventListener(UserModelLocator.LOGIN_YES,switchState); } protected function switchState(event:Event):void { lgView.currentState = "loginState"; } ]]> </fx:Script> <fx:Declarations> <!--初始化服务,里面含有Command注册 和 远程过程调用的信息--> <business:LoginServiceLocator id="lgService" /> <control:LoginController id="loginContr" /> <!--<commands:LoginCommand id="lCommand" />--> <!--<model:UserModelLocator id="uLocator" />--> </fx:Declarations> <view:loginView id="lgView" top="10" horizontalCenter="0" width="30%" height="30%" fontSize="20"/> </s:Application>LoginView.mxml源码如下: <?xml version="1.0" encoding="utf-8"?> <s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" title="请登陆" currentState="initState" creationComplete="lvcreationComplete(event)"> <s:states> <s:State name="initState"/> <s:State name="loginState"/> </s:states> <fx:Script> <![CDATA[ import mx.controls.Alert; import mx.events.FlexEvent; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.validators.Validator; import mx.events.ValidationResultEvent; import mx.core.UIComponent; import net.dreamhui.control.LoginEvent; import net.dreamhui.model.UserModelLocator; import net.dreamhui.vo.UserVO; private var validObjs:Array; protected function lvcreationComplete(event:FlexEvent):void { validObjs = [unSV,pwSV]; // 需要进行验证的对象 } protected function submit(event:MouseEvent):void { var validatorResults:Array; validatorResults = Validator.validateAll(validObjs); if(validatorResults.length == 0) { var user:UserVO = new UserVO(); user.userName = uName.text; user.passWord = pWord.text; var lgEvent:LoginEvent = new LoginEvent(LoginEvent.LOGIN_USER); lgEvent.data = user; lgEvent.dispatch(); //派发事件 /***LoginEvent继承自com.adobe.cairngorm.control.CairngormEvent,* 用父类的方法dispatch派发事件; * 其实CairngormEvent继承自flash.events.Event * dispatch是CairngormEventDispatcher类封装IEventDispatcher * 的dispatchEvent()方法 * **/ } else { var vEvent:ValidationResultEvent;//定义校验出错事件 //取出第一个出错事件 vEvent = validatorResults[0] as ValidationResultEvent; //将光标定位到第一个出错的组件上 (vEvent.target.source as UIComponent).setFocus(); } } ]]> </fx:Script> <fx:Declarations> <!--定义用户名和密码的输入校验类--> <mx:StringValidator id="unSV" source="{uName}" property="text" required="true" maxLength="10" tooLongError="用户名最长为10位" requiredFieldError="请填写用户名" /> <mx:StringValidator id="pwSV" source="{pWord}" property="text" required="true" maxLength="10" tooLongError="密码最长为10位" requiredFieldError="请填写密码" /> </fx:Declarations> <mx:Form includeIn="initState"> <mx:FormItem label="用户名" > <s:TextInput id="uName" /> </mx:FormItem> <mx:FormItem label="密 码" > <s:TextInput id="pWord" displayAsPassword="true" /> </mx:FormItem> <mx:FormItem> <s:Button id="submitBtn" click="submit(event)" label="登陆" right="0" /> </mx:FormItem> </mx:Form> <s:HGroup includeIn="loginState" top="20" left="10" > <s:Label text="欢迎尊贵的用户:"/> <s:Label id="cuName" text="{UserModelLocator.getInstance().currentUser.userName}" /> </s:HGroup> </s:Panel>UserModelLocator.as文件源码如下: package net.dreamhui.model { import com.adobe.cairngorm.CairngormError; import com.adobe.cairngorm.CairngormMessageCodes; import com.adobe.cairngorm.model.ModelLocator; import flash.events.Event; import net.dreamhui.vo.UserVO; //绑定全局View数据 [Bindable] public class UserModelLocator implements ModelLocator { private var _currentUser:UserVO; public static const LOGIN_YES:String = "loginYes"; private static var instance:UserModelLocator; //单例模式 public function UserModelLocator() { if(instance == !null) { throw new CairngormError(CairngormMessageCodes.SINGLETON_EXCEPTION,"UserModelLocator"); } instance = this; } public static function getInstance():UserModelLocator { if(instance == null) { instance = new UserModelLocator(); } return instance; } public function get currentUser():UserVO { return _currentUser; } /** * 此赋值操作绑定loginYes事件,当输入数据合法时候,将改变当前的登录状态 * **/ [Bindable("loginYes")] public function set currentUser(value:UserVO):void { _currentUser = value; dispatchEvent(new Event(UserModelLocator.LOGIN_YES)); } } }LoginEvent.as源码如下: package net.dreamhui.control { import com.adobe.cairngorm.control.CairngormEvent; import net.dreamhui.vo.UserVO; public class LoginEvent extends CairngormEvent { //定义事件类型常量 public static const LOGIN_USER:String = "loginUser"; public function LoginEvent(type:String,bubbles:Boolean=false,cancelable:Boolean=false) { super(type,bubbles,cancelable); } } }LoginController.as源码如下: package net.dreamhui.control { import com.adobe.cairngorm.control.FrontController; import net.dreamhui.commands.LoginCommand; public class LoginController extends FrontController { public function LoginController() { initCommands(); } /**注册Command*/ private function initCommands():void { addCommand(LoginEvent.LOGIN_USER,LoginCommand); } } }LoginCommand.as源码如下: package net.dreamhui.commands { import com.adobe.cairngorm.commands.ICommand; import com.adobe.cairngorm.control.CairngormEvent; import mx.controls.Alert; import mx.rpc.IResponder; import net.dreamhui.business.LoginDelegate; import net.dreamhui.control.LoginEvent; import net.dreamhui.model.UserModelLocator; import net.dreamhui.vo.UserVO; public class LoginCommand implements ICommand,IResponder { public function LoginCommand() { } public function execute(event:CairngormEvent):void { var lgEvent:LoginEvent = LoginEvent(event); var user:UserVO = lgEvent.data; var delegate:LoginDelegate = new LoginDelegate(this); delegate.login(user); // 与后台的login方法名要相同 } /** * Command实现IResponder接口的两个方法result和fault; * 我看了两份教程,前者是这样的: * 1、Command实现com.adobe.cairngorm.business.Responder接口的onResult和onFault两个方法; * 2、Command实现mx.rpc.IResponder接口的两个方法result和fault; * 因为我在LoginDelegate没能实现将内部变量设置为com.adobe.cairngorm.business.Responder, * 所以,我采用了第二种方案,通过。 * */ // 收到返回值后由服务调用此方法 public function result(event:Object):void { var cuUser:UserVO = event.result as UserVO; if(cuUser) { UserModelLocator.getInstance().currentUser = cuUser; //此赋值操作绑定loginYes事件,当输入数据合法时候,将改变当前的登录状态 }else{ Alert.show("用户名或密码错误,请重新填写"); } } // 收到错误后由服务调用此方法 public function fault(event:Object):void { trace("服务调用错误"+event.toString()); } } }LoginDelegate.as源码如下: package net.dreamhui.business { import com.adobe.cairngorm.business.ServiceLocator; import mx.rpc.IResponder; import net.dreamhui.vo.UserVO; public class LoginDelegate { public var responder:IResponder; public var service:Object; public function LoginDelegate(responder:IResponder) { this.service = ServiceLocator.getInstance().getRemoteObject("loginService"); //this.service = ServiceLocator.getInstance().getService("loginService"); //我看的教程里采用下面的做法,程序运行没有问题,只是会有warning this.responder = responder; } public function login(user:UserVO):void { var call:Object = service.login(user); // 必须与远程的方法相对应 //call.resultHandler = Delegate.create(responder,responder.onResult); //call.faultHandler = Delegate.create(responder,responder.onFault); //注释掉的部分是教程里的写法,可能是版本的问题,在我这儿是不对的 call.addResponder(responder); } } }LoginServiceLocator.mxml文件源码如下: <?xml version="1.0" encoding="utf-8"?> <cairngorm:ServiceLocator xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:cairngorm="http://www.adobe.com/2006/cairngorm"> <fx:Declarations> <s:RemoteObject id="loginService" destination="loginUser" showBusyCursor="true" /> </fx:Declarations> </cairngorm:ServiceLocator> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- c# – ServiceStack在没有MVC的情况下启用Razor
- Ehcache 缓存(二)xml配置相关
- Oracle数据库之安装教程
- swift – 后台获取中多个异步请求的最佳实践是什
- ios – 在UICollectionView中注册多个单元格(swi
- c# – mvc PartialView with Dialog Partial Vie
- Metasploit4.2pro MSF连接postgresql编码错误问题
- Confluence 6 找到在创建 XML 备份的时候出现的错
- 把DSP TMS320F28XXX的程序段从flash复制到ram中运
- c – 如何迭代一个向量,也知道元素的索引?