Flex之应用Cairngorm(4) - Cairngorm Extensions
Flex之使用Cairngorm(4) - Cairngorm Extensions
Previous Posts:
1.准备工作 http://nealmi.iteye.com/blog/164867
2.使用ModelLocator http://nealmi.iteye.com/blog/164879
3.Command & Event http://nealmi.iteye.com/blog/177370
Cairgorm Step By Step教程[推荐]
http://www.davidtucker.net/category/cairngorm/(英文)
下载源码:
后台指向我的Google App Engine 程序, 你可以暂时不关心后台, 直接导入到FlexBuilder里运行.
http://nealmi.iteye.com/topics/download/2e854ac3-89b2-3f15-814b-e4317380608e
就我个人来说,Cairngorm有两个致命的问题,直接影响到我是否使用它.
1.不支持通知视图.
Cairngorm2.1之前可以用ViewHelper 和 ViewLocator,但是自从Cairngorm2.1开始已经不推荐了.而且 ViewHelper和ViewLocator 方式本身就违反MVC.
2.不支持子Controller.
所以我选择了使用 UM Cairngorm Extensions. http://code.google.com/p/flexcairngorm/
Refactor To UM Cairngorm Extensions:
1.重构Event.继承com.universalmind.cairngorm.events.UMEvent.
在构造函数里接受一个IResponder类型的参数(用作通知视图), UMEvent 本身带有一个data属性.
2.重构Controller.继承com.universalmind.cairngorm.control.FrontController.增加对子Controller的支持,可以通过addSubController(..)方法来添加子Controller.这样可以每个独立的模块有独立MVC结构.
3.重构Command.继承com.universalmind.cairngorm.commands.Command.这里通过用了一种可以减少类文件的写法.(cairngorm继承了JEE中大量的垃圾.类爆炸就是其中之一).
3.重构Delegate, 继承com.universalmind.cairngorm.business.Delegate.
6.View代码.
6.注意Value Object的写法.要实现com.universalmind.cairngorm.vo.IValueObject接口.实现copyFrom 和Clone方法.
以上只是粗略的介绍.有什么问题可以联系我通过邮件 imzw.net+javaeye at gmail.com.
-------------
IT'S NEAL.
Previous Posts:
1.准备工作 http://nealmi.iteye.com/blog/164867
2.使用ModelLocator http://nealmi.iteye.com/blog/164879
3.Command & Event http://nealmi.iteye.com/blog/177370
Cairgorm Step By Step教程[推荐]
http://www.davidtucker.net/category/cairngorm/(英文)
下载源码:
后台指向我的Google App Engine 程序, 你可以暂时不关心后台, 直接导入到FlexBuilder里运行.
http://nealmi.iteye.com/topics/download/2e854ac3-89b2-3f15-814b-e4317380608e
就我个人来说,Cairngorm有两个致命的问题,直接影响到我是否使用它.
1.不支持通知视图.
Cairngorm2.1之前可以用ViewHelper 和 ViewLocator,但是自从Cairngorm2.1开始已经不推荐了.而且 ViewHelper和ViewLocator 方式本身就违反MVC.
2.不支持子Controller.
所以我选择了使用 UM Cairngorm Extensions. http://code.google.com/p/flexcairngorm/
Refactor To UM Cairngorm Extensions:
1.重构Event.继承com.universalmind.cairngorm.events.UMEvent.
在构造函数里接受一个IResponder类型的参数(用作通知视图), UMEvent 本身带有一个data属性.
import com.universalmind.cairngorm.events.UMEvent; public class LoginEvent extends UMEvent{ public static const LOGIN:String = "login"; public function LoginEvent(user:UserVO=null, callbacks:IResponder=null){ super(LOGIN, callbacks, true, true, user); } public function get user():UserVO{ trace("LoginEvent - user() - " + data); return data as UserVO; }
2.重构Controller.继承com.universalmind.cairngorm.control.FrontController.增加对子Controller的支持,可以通过addSubController(..)方法来添加子Controller.这样可以每个独立的模块有独立MVC结构.
import com.universalmind.cairngorm.control.FrontController; public class UserController extends FrontController { public function UserController(){ super(); this.init(); } private function init():void{ this.addCommand(LoginEvent.LOGIN, UserCommand); //Add sub controller via addSubController(...); } }
3.重构Command.继承com.universalmind.cairngorm.commands.Command.这里通过用了一种可以减少类文件的写法.(cairngorm继承了JEE中大量的垃圾.类爆炸就是其中之一).
public class UserCommand extends Command{ override public function execute(event:CairngormEvent):void{ super.execute(event); switch(event.type){ case LoginEvent.LOGIN: doLogin(event as LoginEvent); break; case RegistrationEvent.REGISTRATION: doRegistration(event as RegistrationEvent); break; default: trace("Unkonw event type [" + event.type +"]"); } } private function doLogin(event:LoginEvent):void{ var delegate:UserDelegate = new UserDelegate(event.callbacks); trace("LoginCommand - doLogin - " + event.user); delegate.login(event.user); } private function doRegistration(event:RegistrationEvent):void{ var delegate:UserDelegate = new UserDelegate(event.callbacks); trace("LoginCommand - doLogin - " + event.user); //delegate.register(event.user); }
3.重构Delegate, 继承com.universalmind.cairngorm.business.Delegate.
public function UserDelegate(commandHandlers:IResponder=null){ //userService 声明在Services.mxml里. super(commandHandlers, "userService"); } public function login(user:UserVO):void { trace("UserDelegate.login() - " + user); //这里多加了一层,你可以在这里将服务器返回的结果加以处理,比如:将XML结果组装成Value Object, 过滤掉某些数据等. var token: AsyncToken = service.login(user.loginName, user.password); var callbacks:Callbacks = new Callbacks(resultNotifyer, faultNotifyer); prepareHandlers(token, callbacks); } private function resultNotifyer(event:ResultEvent):void{ //Alert.show(event.result + "","result"); trace("resultNotifyer - " + event ); // You can do something like filter data at here. eg: decode json . // Code sample - Decode json: // ------------------------------ // var rawData:String = event.result; // var obj:Object = JSON.decode(rawData); // var e:ResultEvent = new ResultEvent() // e.resulte = obj; // notifyCaller(e); //通知视图,也可以在Command里执行. notifyCaller(event); } private function faultNotifyer(event:FaultEvent):void{ //Alert.show(event.fault+"","fault"); trace("faultNotifyer - " + event ); notifyCaller(event); }
6.View代码.
<?xml version="1.0" encoding="utf-8"?> <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ import mx.utils.StringUtil; import com.universalmind.cairngorm.events.Callbacks; import net.imzw.UserManagerDemo.event.LoginEvent; import mx.rpc.IResponder; import mx.rpc.events.ResultEvent; import mx.rpc.events.FaultEvent; import net.imzw.UserManagerDemo.vo.UserVO; import net.imzw.UserManagerDemo.model.UserManagerModelLocator; import mx.controls.Alert; private var modelLocator:UserManagerModelLocator = UserManagerModelLocator.getInstance(); private function login(e:MouseEvent):void{ //组装Callback. var callbacks:IResponder = new Callbacks(resultHandler, faultHandler); var user:UserVO = new UserVO(StringUtil.trim(loginNameTextInput.text), StringUtil.trim(passwordTextInput.text)); var loginEvent:LoginEvent = new LoginEvent(user, callbacks); trace("doSignIn - " + loginEvent); loginEvent.dispatch(); } private function resultHandler(event:ResultEvent):void{ if(event.result == null){ Alert.show("登录名或密码错误.", "Error"); //登录名或密码错误时,设置焦点到用户名TextInput,标准的Cairgorm很难做到指点. loginNameTextInput.setFocus(); }else{ trace(event.result.loginName + ""); // Here should can simple like following code, but I got an error. // May be case by fields mismatch between flex and backend. // modelLocator.currentUser = event.result as UserVO; var user:UserVO =new UserVO(event.result.loginName); trace(user.loginName); modelLocator.currentUser = user; trace(modelLocator.currentUser.loginName); modelLocator.workflowState = UserManagerModelLocator.MAIN_SCREEN; reset(); } } private function faultHandler(event:FaultEvent):void{ trace(event.message + ""); Alert.show( "服务器错误, 请稍候再试.", "Error"); } private function reset():void{ loginNameTextInput.text = ""; passwordTextInput.text = ""; } ]]> </mx:Script> <mx:Form defaultButton="{loginButton}" borderSides="left right top bottom" borderStyle="solid" borderColor="green"> <mx:FormHeading label="Please Login" /> <mx:FormItem label="LoginName"> <mx:TextInput id="loginNameTextInput" /> </mx:FormItem> <mx:FormItem label="Password"> <mx:TextInput id="passwordTextInput" displayAsPassword="true"/> </mx:FormItem> <mx:HBox horizontalAlign="right" width="100%"> <mx:Button id="loginButton" click="{login(event)}" label="Login" /> </mx:HBox> </mx:Form> </mx:VBox>
6.注意Value Object的写法.要实现com.universalmind.cairngorm.vo.IValueObject接口.实现copyFrom 和Clone方法.
package net.imzw.UserManagerDemo.vo{ import com.universalmind.cairngorm.vo.IValueObject; [Bindable] public class UserVO implements IValueObject{ public var id:Number; public var loginName:String; public var password:String; public function UserVO( loginName:String=null, password:String=null ){ this.loginName = loginName; this.password = password; } public function copyFrom(src:*):*{ this.loginName = src.loginName; this.password = src.password; } public function clone():*{ return new UserVO(loginName, password); } public function equals(anotherUser:*):Boolean{ if(null == anotherUser) return false; if(id == anotherUser.id && loginName == anotherUser.loginName){ return true; } return false; } public function toString():String{ return "User[loginName:"+loginName+"]"; } } }
以上只是粗略的介绍.有什么问题可以联系我通过邮件 imzw.net+javaeye at gmail.com.
-------------
IT'S NEAL.