Cairngorm示例:用户登录


1. Cairngorm简介

Cairngorm是一个Flex程序开发框架,基于MVC设计模式。
使用Cairngorm进行开发时我们一般涉及以下几个部件的开发:

ModelLocator:定义Model。ActionScript类,一般采用singleton模式实现,必须
              是Bindable的
ServiceLocator:定义与之进行通讯的服务器端的服务。MXML Component
Event:继承CairngormEvent
Command:处理Event的逻辑。实现ICommand接口
Controller:注册Event与Command之间的对应关系。继承FrontController
Delegate:服务器端服务的代理。ActionScript类

以用户输入数据、点击确定按钮,客户端与服务器通讯,然后根据处理结果进行相应操
作这一典型的处理过程为例,确定按钮事件中,用户数据被附加到Event上然后发布,
Cairngorm根据Controller中注册的信息,找到处理该Event的Command,该Command通过
ServiceLocator获得相应的远程服务,从Event中提取用户数据发送到远程服务,响应回
来后,Command根据响应数据,通过ModelLocator修改数据,由于ModelLocator和页面数
据是Bind在一起的,所以也就相应地修改了画面的显示。

2. 示例

以下是用户输入ID、password进行登录的示例代码,当ID、password都是“test”的时候,
登录成功,画面转到有主菜单的画面。

服务器端简单地实现了一个服务,代码如下:
public class UserService {
	public boolean isValid(String username, String password) {
		if ("test".equals(username) && "test".equals(password)) {
			return true;
		} else {
			return false;
		}
	}
}


客户端代码的包结构如下(其中方括弧表示包),其中没有使用Delegate:
  login.mxml
  [business]
      Controller.as
  Services.mxml
  [commands]
      LoginCommand.as
  [events]
      LoginEvent.as
  [model]
      ModelLocator.as

ModelLocator代码如下:
package model
{
	[Bindable]
	public class ModelLocator
	{
		static private var _instance : ModelLocator = null;
		
		public var showLoginPanel : Boolean = true;
		public var currentState : String = "";
		
		static public function getInstance() : ModelLocator
		{
			if (_instance == null) {
				_instance = new ModelLocator();
			}
			return _instance;
		}
	}
}

ServiceLocator代码如下:
<?xml version="1.0" encoding="utf-8"?>
<rds:ServiceLocator xmlns:rds="com.adobe.cairngorm.business.*" 
                    xmlns:mx="http://www.adobe.com/2006/mxml">
	<mx:RemoteObject 
		id="userService" 
		destination="userServiceDestination" 
		endpoint="http://localhost:8080/test-server/messagebroker/amf">
	</mx:RemoteObject>
</rds:ServiceLocator>

Event代码如下:
package business.events
{
	import com.adobe.cairngorm.control.CairngormEvent;

	public class LoginEvent extends CairngormEvent
	{
		static public var EVENT_ID:String="login";
		public var username : String = null;
		public var password : String = null;
		
		public function LoginEvent()
		{
			super(EVENT_ID);
		}
	}
}

Command代码如下:
package business.commands
{
	import com.adobe.cairngorm.business.ServiceLocator;
	import com.adobe.cairngorm.commands.ICommand;
	import com.adobe.cairngorm.control.CairngormEvent;
	
	import mx.rpc.events.ResultEvent;
	import mx.rpc.remoting.RemoteObject;

	import model.ModelLocator;
	import business.events.LoginEvent;
	
	public class LoginCommand implements ICommand
	{
		private var _modelLoc : ModelLocator = ModelLocator.getInstance();
		private var _serviceLoc : ServiceLocator = ServiceLocator.getInstance();
		
		public function execute(event:CairngormEvent):void
		{
			var loginEvent : LoginEvent = LoginEvent(event);
			var userService : RemoteObject = _serviceLoc.getRemoteObject("userService");
			userService.addEventListener(ResultEvent.RESULT, onResults_login);
			userService.getOperation("isValid").send(loginEvent.username, loginEvent.password);
		}
		
		private function onResults_login(event:ResultEvent):void
		{
			var isValid : Boolean = Boolean(event.result);
			if (isValid) {
				_modelLoc.showLoginPanel = false;
				_modelLoc.currentState = "mainmenu";
			}
		}
	}
}

Controller代码如下:
package business
{
	import com.adobe.cairngorm.control.FrontController;

	import business.events.LoginEvent;
	import business.commands.LoginCommand;

	public class Controller extends FrontController
	{
		public function Controller()
		{
			super();
			this.addCommand(LoginEvent.EVENT_ID, LoginCommand);
		}
	}
}

最后登录画面代码如下
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
	width="100%" height="100%" verticalAlign="middle" horizontalAlign="center" 
	fontFamily="Courier New" fontSize="12" currentState="{_model.currentState}">
	<mx:states>
		<mx:State name="mainmenu">
			<mx:RemoveChild target="{panel1}"/>
			<mx:AddChild position="lastChild">
				<mx:MenuBar id="mainMenu" width="100%" x="0" y="0" labelField="@label">
					<mx:XMLList>
						<menuitem label="数据录入">
							<menuitem label="顾客信息登记" />
							<menuitem label="印刷订单录入" />
						</menuitem>
						<menuitem label="帮助">
							<menuitem label="帮助" />
							<menuitem label="关于" />
						</menuitem>
					</mx:XMLList>
				</mx:MenuBar>
			</mx:AddChild>
			<mx:SetProperty name="layout" value="absolute"/>
		</mx:State>
	</mx:states>
	<mx:Panel width="370" height="192" layout="absolute" title="登録" id="panel1" visible="{_model.showLoginPanel}">
		<mx:Label text="姓 名:" x="44" y="21" width="91"/>
		<mx:TextInput x="143" y="19" id="txtUsername" maxChars="32"/>
		<mx:Label x="44" y="51" text="密 码:" width="91"/>
		<mx:TextInput x="143" y="49" id="txtPassword" maxChars="32" displayAsPassword="true"/>
		<mx:Button x="70" y="118" label="登录" id="btnLogin" click="btnLogin_clicked()" width="92"/>
		<mx:Button x="170" y="118" label="重置" id="btnReset" click="btnReset_clicked()" width="92"/>
	</mx:Panel>



	<mx:Script>
		<![CDATA[
			import model.ModelLocator;
			import business.events.LoginEvent;
		
			[Bindable]
			private var _model:ModelLocator=ModelLocator.getInstance();
		
			private function btnLogin_clicked() : void
			{
				var event : LoginEvent = new LoginEvent();
				event.username = txtUsername.text;
				event.password = txtPassword.text;
				event.dispatch();
			}
			
			private function btnReset_clicked() : void
			{
				//略
			}
		]]>
	</mx:Script>
	
	<rds:Services xmlns:rds="business.*"/>
	
	<router:Controller xmlns:router="business.*"/>
	
</mx:Application>

其中需要注意的是Application的currentState和登录窗口的visible属性是bind到ModelLocator的。

你可能感兴趣的:(设计模式,xml,Flex,Adobe,actionscript)