`
iMzw
  • 浏览: 193515 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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属性.
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.
4
0
分享到:
评论

相关推荐

    Flex之使用Cairngorm(3) - Command & Event

    标题提到的“Flex之使用Cairngorm(3) - Command & Event”,意味着这个系列文章已经讲解了Cairngorm的基础知识,现在将更深入地探讨Command模式和Event机制,这两个是Cairngorm中关键的交互元素。 Command模式是...

    Flex之使用Cairngorm(2) - 使用ModelLocator

    源码(包含Cairngorm.swc) 博文链接:https://nealmi.iteye.com/blog/164879

    Flex-cairngorm-demo我喜欢的

    "Flex-cairngorm-demo我喜欢的"是一个基于Cairngorm框架的示例项目,开发者对其表现出了浓厚的兴趣。 Cairngorm的核心概念包括: 1. **Model**: 模型层负责处理业务逻辑和数据管理,通常与后端服务进行交互。它保持...

    Flex login flex cairngorm

    Cairngorm是Flex社区中广泛使用的轻量级MVC(模型-视图-控制器)框架,它帮助开发者组织和管理复杂的Flex项目。在“Flex login flex cairngorm”这个主题中,我们将探讨如何使用Cairngorm框架实现登录功能。 1. **...

    Flex开发框架cairngorm入门实例教程

    4. **服务(Service)/命令(Command)**:虽然在提供的内容中没有直接涉及,但Cairngorm通常使用命令模式处理业务逻辑。当控制器接收到事件后,会调用相应的Command来执行业务逻辑,例如保存新添加的图书到数据库。...

    Cairngorm-Flex.zip_Cairngorm_flex

    Cairngorm框架是Adobe Flex开发中的一种著名轻量级MVC(Model-View-Controller)框架,由Adobe公司的专业团队设计,旨在提高Flex应用程序的可维护性和可扩展性。这个框架的核心理念是通过分离业务逻辑、用户界面和...

    flex框架之Cairngorm框架(一)

    flex框架之Cairngorm框架,包括Cairngorm框架

    跟我StepByStep学FLEX教程------王一松

    Java&Flex之RemoteObject - **RemoteObject组件**:介绍如何使用RemoteObject组件与Java服务器进行通信。 - **消息传递**:演示如何发送和接收数据。 #### 25. AMF - **AMF简介**:AMF(Action Message Format)...

    flex框架之Cairngorm框架(二)

    在“flex框架之Cairngorm框架(二)”这个主题中,我们可能深入探讨如何使用Cairngorm与后台进行通信。这通常涉及以下步骤: 1. **创建Command**:首先,为与后台的通信创建一个命令类,例如`...

    Flex框架Cairngorm经典案例源码

    Cairngorm是Flex社区中流行的一种轻量级MVC(Model-View-Controller)框架,它提供了一种结构化的方法来组织和管理Flex项目的代码,从而提高开发效率和代码可维护性。 Cairngorm框架的核心组件包括: 1. **模型...

    Flex 使用 Cairngorm 框架与java进行数据交互

    前台FLex工程(单独工程Cairngorm)使用Cairngorm框架与后台java工程(FLexToJava)进行数据交互。功能点: ①flex提交表单保存到数据库; ②flex向后台请求,后台返回List集合,flex将集合填充到combox 附带:...

    flex-Cairngorm框架

    Flex Cairngorm框架详解 Flex Cairngorm框架是Adobe Flex应用程序开发中的一个流行的设计模式,它基于Model-View-Controller(MVC)架构,旨在提高代码的可维护性和可扩展性。Cairngorm框架由SitePen公司开发,最初...

    Flex3+Cairngorm+Spring的增删改查模块

    Flex3+Cairngorm+Spring的增删改查模块是一个典型的富互联网应用程序(RIA)开发实例,它结合了Adobe Flex3、Cairngorm框架和Spring框架,为小型用户提供了一个全面的CRUD(Create, Read, Update, Delete)功能。...

Global site tag (gtag.js) - Google Analytics