存档在 2010年1月16日

[转载]跟我StepByStep学FLEX教程——Cairngorm之Command部分

2010年1月16日

这一讲对Command部分进行详细解释,也就是command如何通过Delegate部分去做Services(Remoting,Webservices…等等)。

  从上一讲中读者可以知道,Event触发通过FrontController影射到对应的Command进行业务处理。

  而如果系统要和后台的数据库进行数据交互的话,Command就会产生Delegate,将远程访问(HTTP,WebServices等等)实例化,并将结果返回给Command。

  Service则就是用来定义服务器端访问以获取数据的。

  这样读者就很清晰Command部分的处理流程了,对照代码解释如下:

  LoadPhotosCommand.as中需要加载图片访问服务器数据(该实例简化就定义在本地xml中,不过原理一样的),通过onResults_loadPhotos这个,将获取的图片数据加载到ModelLocator中,这样View就可以显示所获取的数据了。

  而在PhotoDelegate中,就是将远程访问实例化而已:__service = __locator.getHTTPService(”photosIn”);

  Services.mxml中定义了访问数据的方式:<mx:HTTPService id=”photosIn” url=”assets/photos.xml”/>。

  读者通过Demo15及对其的详细讲解,应该有一个很基础的认知了,至于框架本身如何,在实际系统的开发中,都要很好的去遵循框架本身的要求。

[转载]跟我StepByStep学FLEX教程——Cairngorm之Model Locator

2010年1月16日

  Model Locator的概念已经讲过,就是在一个地方存储程序中所有的值对象(ValueObjects,数据)并共享变量。

  也就是说,Model Locator用来集中管理程序所需要的变量。

  下边把Demo15的ModelLocator.as代码如下:(作者增加相应的注释)

?View Code ACTIONSCRIPT
import mx.collections.ArrayCollection;
 
 [Bindable]
 public class ModelLocator
 {
 
  //定义程序需要的变量,作者建议读者把该部分定义放在最下边,而不是示例中的上边,原因就是在于代码更整齐(因人而异,仅作者的个人建议,呵呵)
  public var photoData:ArrayCollection=new ArrayCollection();
  public var purchasedPhotos:ArrayCollection=new ArrayCollection();
 
  
 
  //定义ModelLocator的Single Instance,这就是设计模式的单例模式(不明白的读者可以看设计模式中的该模式讲解)
  static private var __instance:ModelLocator=null;
  //返回single instance
  static public function getInstance():ModelLocator
  {
   if(__instance == null)
   {
    __instance=new ModelLocator();
   }
   return __instance;
  }
 }

  对于ModelLocator的instance和getInstance的代码编写,这部分代码读者在写新的代码过程中,除非重新定义一个自己的ModelLocator(基于IModelLocator 接口实现),这部分代码就这么写了,呵呵,即使是自己定义,其也大同小异。

  对于getInstance来说,会判断程序是否已经有ModelLocator的实例,如果有则读取,没有则创建。

  而[Bindable]的特性,使自己定义的变量在任何一个使用定义变量的地方自动更新,这也是ModelLocator的共享变量的概念所在。

  ValueObject下的photo.as对象作者就不解释了,实在没啥解释的,呵呵。

  下一讲就要对Cairngorm的核心控制流程进行讲解了,也就是bussiness下的各部分和event的复杂关系,可能读者刚接触会觉得很绕,没关系,呵呵,Step By Step,作者讲解之后,读者就不会有那种感觉了。

  作者很感谢广大读者的支持,看见大家的评价,心里甚感欣慰,呵呵。

[转载]跟我StepByStep学FLEX教程——Cairngorm之核心控制流程

2010年1月16日

这一讲结合Demo对Cairngorm的核心控制流程进行讲解,也帮助读者梳理一下对Demo代码的认知。

  下图就是Caringorm的事件流程:

跟我StepByStep学FLEX教程------Cairngorm之核心控制流程

  在操作View也就是页面的过程中会派发Event,然后由Front Controller影射分配给对应的Command,Command做完相应的业务处理更新ModelLocator的数据,由于ModelLocator(上一讲讲过)共享的原因,View自动会更新所显示的内容。

  了解了这个基本流程后,读者对核心控制流程的认知就会更加清晰了:

  Events:就是操作View或者其它设计产生的事件;

  FrontController:就是注册Command和Event的对应关系,来把Event进行影射分配给相应的Command;

  Command:进行业务处理,更新ModelLocator(至于Command部分如何利用Delegate和Service连接则在下一讲中进行详细描述);

  这下读者就很清楚了这三者之间的关系以及Cairngorm这么做的基本原理。

  很显然,也就对应了以下的代码结构:

跟我StepByStep学FLEX教程------Cairngorm之核心控制流程

  events目录下的AddPhotoToCartEvent.as和LoadPhotosEvent.as,继承自CairngormEvent。PhotoEvent让操作者选择图片时发出事件(FStop.mxml中操作事件触发)。

  在FSController.as中定义(建议读者建一个controller的目录),继承自FrontController,负责将Event注册到Command,也就是接收到Event就分配给Command,代码如下:

?View Code ACTIONSCRIPT
addCommand(LoadPhotosEvent.EVENT_ID,LoadPhotosCommand);
addCommand(AddPhotoToCartEvent.EVENT_ID,AddPhotoToCartCommand);

在FStop.mxml中操作者触发代码:

?View Code ACTIONSCRIPT
     //选择图片时触发AddPhotoToCartEvent
 
   private function photoSelectedHandler(event:PhotoEvent):void
   {
    var addEvent:AddPhotoToCartEvent=new AddPhotoToCartEvent(event.selectedPhoto);
    addEvent.dispatch();
   }
 
   //初始化系统时触发LoadPhotosEvent
 
   private function initApp():void
   {
    var event:LoadPhotosEvent=new LoadPhotosEvent();
    event.dispatch();
   }

这下读者对代码是不是清晰很多了:)

  下一讲对Command如何利用Delegate和Service连接进行讲解(说句实话,尽管作者也遵照这个规范去编写,但是仍然感觉Cairngorm架构对业务层的处理定义的过于复杂了,仅个人观点,非官方,呵呵)。

[转载]跟我StepByStep学FLEX教程——Cairngorm之代码结构

2010年1月16日

首先看看Demo15的详细代码结构如下图:
跟我StepByStep学FLEX教程------Cairngorm之代码结构

  其中,assets为系统用到的图片以及CSS样式和XML数据。

  下边大家可以按照Cairngorm之组成部分那一讲的图片和概念对照,对其程序的组成部分就很清晰了,有一个很直观的认识。

  大家很容易明白FStop.mxml是运行系统的主页面文件,而views下的mxml都是组成主页面的页面组件。这些就不具体讲解了,在后边,会把页面的一些和Cairngorm相关的在后边的讲解中会一起说明,而页面本身的大家可以看看教程的初级部分。

  下一讲就讲model部分的代码进行讲解,这个相对来说也简单。之后就要对bussiness和events这两部分进行重点讲解,一般读者如果没有一定基础的话,不容易理解。

[转载]cairngorm登陆设计

2010年1月16日

听到一个网友讲了他的需求,所以花了点时间写了这个东西,顺便开了个博客,以前感觉自己写的东西拿不出来见人,但是这样自己就得不到发展,希望能对入门开发人员有点启示,高手们多加指导,作为一个业余爱好者,大学四年来,网络给予我很多的东西,帮助了我很多,网络作为我大学时代的唯一老师,我很是感激,希望终有一天自己能够为中国的开源程序发展做出丁点(毕竟能力是有限的)。特此感谢其他写程序博客人们,你们每一个都是无私的老师,能够与其他人分享开发的快乐。 同时也祝愿自己能够找到工,克服危机,加油!!! 程序只是展现流程而已,大家自行补充完整,service是没有发送任何东西的,php页面会返回一个字符串。

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
LoginService.as
package com.steps.Player.business
{
	import com.steps.Player.vo.UserLoginInfo;
 
	import mx.rpc.AsyncToken;
	import mx.rpc.IResponder;
	import com.adobe.cairngorm.business.ServiceLocator;
 
	public class LoginService
	{
		private var responder:IResponder;
		private var service:Object;
		public function LoginService(responder:IResponder)
		{
			this.responder=responder;
			this.service=ServiceLocator.getInstance().getHTTPService("LoginService");
		}
		public function login(userloginInfo:UserLoginInfo):void
		{
			var token:AsyncToken=service.send();
			token.addResponder(responder);
		}
 
	}
}
 
 
LoginManageCommand.as
package com.steps.Player.command
{
	import com.adobe.cairngorm.commands.ICommand;
	import com.adobe.cairngorm.control.CairngormEvent;
	import com.steps.Player.business.LoginService;
	import com.steps.Player.event.UserLoginEvent;
	import com.steps.Player.view.PopupTitleWindow;
 
	import flash.display.DisplayObject;
 
	import mx.managers.PopUpManager;
	import mx.rpc.IResponder;
 
	public class LoginManageCommand implements ICommand, IResponder
	{
		private var parent:DisplayObject;
		public function execute(event:CairngormEvent):void
		{
			if(event.type==UserLoginEvent.unLogin)
			{
				var login:PopupTitleWindow=PopupTitleWindow(PopUpManager.createPopUp((event as UserLoginEvent).parent,PopupTitleWindow,true))
				PopUpManager.centerPopUp(login);
			}
			if(event.type==UserLoginEvent.login)
			{
				this.parent=(event as UserLoginEvent).parent;
				var delegate:LoginService=new LoginService(this);
				delegate.login((event as UserLoginEvent).userLoginInfo);
			}
		}
 
		public function result(data:Object):void
		{
			PopUpManager.removePopUp(this.parent as PopupTitleWindow);
		}
 
		public function fault(info:Object):void
		{
		}
 
	}
}
 
 
LoginControl.as
package com.steps.Player.control
{
	import com.adobe.cairngorm.control.FrontController;
	import com.steps.Player.event.UserLoginEvent;
	import com.steps.Player.command.LoginManageCommand;
	public class LoginControl extends FrontController
	{
 
		public function LoginControl()
		{
			addCommand(UserLoginEvent.unLogin,LoginManageCommand);
			addCommand(UserLoginEvent.login,LoginManageCommand);
		}
 
	}
}
 
 
UserLoginEvent.as
package com.steps.Player.event
{
	import com.adobe.cairngorm.control.CairngormEvent;
 
	import com.steps.Player.vo.UserLoginInfo;
 
	import flash.display.DisplayObject;
	import flash.events.Event;
 
	public class UserLoginEvent extends CairngormEvent
	{
		public static const unLogin:String="unLogin";
		public static const login:String="login";
		public var userLoginInfo:UserLoginInfo;
		public var parent:DisplayObject;
		public function UserLoginEvent(type:String,parent:DisplayObject)
		{
			super(type);
			this.parent=parent;
		}
		override public function clone():Event
		{
			return new UserLoginEvent(type,parent);
		}	
		public function set loginInfo(userLoginInfo:UserLoginInfo):void
		{
			this.userLoginInfo=userLoginInfo;
		}
		public function get loginInfo():UserLoginInfo
		{
			return this.userLoginInfo;
		}
	}
}
 
Login.as
package com.steps.Player.model
{
	import com.steps.Player.vo.UserLoginInfo;
 
 
	public class Login
	{
 
		[Bindable]
		public var userLoginInfo:UserLoginInfo=new UserLoginInfo();
 
 
 
	}
}
 
ModelLocator.as
package com.steps.Player.model
{
	[Bindable]
	public class ModelLocator
	{
 
 
		static private var __instance:ModelLocator=null;
		static public function getInstance():com.steps.Player.model.ModelLocator
		{
			if(__instance==null)
			{
				__instance=new ModelLocator();
			}
			return __instance;
		}
		public function ModelLocator()
		{
 
		}
		public var login:Login=new Login();
 
	}
 
}
 
 
&nbsp;PopupTitleWindow.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" title="登陆" layout="absolute" width="400" height="300">
	<mx:Script>
		<![CDATA[
			import com.steps.Player.vo.UserLoginInfo;
			import com.steps.Player.event.UserLoginEvent;
			import mx.events.ModuleEvent;
			import com.adobe.cairngorm.control.CairngormEventDispatcher;
			private function onLogin(event:MouseEvent):void
			{
				var userLoginInfo:UserLoginInfo=new UserLoginInfo();
				userLoginInfo.userName=username.text;
				userLoginInfo.userPassword=password.text;
				var evt:UserLoginEvent=new UserLoginEvent(UserLoginEvent.login,this);
				evt.loginInfo=userLoginInfo;
				CairngormEventDispatcher.getInstance().dispatchEvent(evt);	
			}
		]]>
	</mx:Script>
	<mx:Form x="67" y="59">
		<mx:FormItem label="用户名:">
			<mx:TextInput id="username"/>
		</mx:FormItem>
		<mx:FormItem label="密码:">
			<mx:TextInput id="password"/>
		</mx:FormItem>
 
	</mx:Form>
	<mx:Button label="登陆" click="onLogin(event)" x="255" y="159"/>
	<mx:Button x="199" y="159" label="清空"/>
</mx:TitleWindow>
 
UserLoginInfo.as
package com.steps.Player.vo
{
	import com.adobe.cairngorm.vo.ValueObject;
 
	public class UserLoginInfo implements ValueObject
	{
 
		public var userName:String="";
		public var userPassword:String="";
		public var isLogin:Boolean=false;
		public function UserLoginInfo()
		{
		}
 
	}
 
}
 
 
popuptest.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
	xmlns:business="com.steps.Player.business.*"
	xmlns:control="com.steps.Player.control.*"
	xmlns:view="com.steps.Player.view.*"
	 layout="absolute"
    creationComplete="init()">
	<mx:Script>
		<![CDATA[
			import com.steps.Player.event.UserLoginEvent;
			import com.steps.Player.model.Login;
			import com.steps.Player.event.UserLoginEvent;
			import com.steps.Player.model.ModelLocator;
			import com.adobe.cairngorm.control.CairngormEventDispatcher;
			private var __model:ModelLocator=ModelLocator.getInstance();
			private function init():void
			{
				if(!__model.login.userLoginInfo.isLogin)
				{
					var event:UserLoginEvent=new UserLoginEvent(UserLoginEvent.unLogin,this);
					CairngormEventDispatcher.getInstance().dispatchEvent(event);
				}
			}
		]]>
	</mx:Script>
	<control:LoginControl id="LoginControl"/>
	<business:services id="LoginService"/>
</mx:Application>
&nbsp;
services.mxml
<?xml version="1.0" encoding="utf-8"?>
<rds:ServiceLocator xmlns:rds="com.adobe.cairngorm.business.*" xmlns:mx="http://www.adobe.com/2006/mxml">
	<mx:HTTPService id="LoginService" useProxy="false" url="http://localhost/popuptest/bin-debug/login.php" resultFormat="text" method="get">
 
	</mx:HTTPService>
</rds:ServiceLocator>

推荐60+ Flex开发参考网站

2010年1月16日

新手入门参考:

应用收集,文章,博客,流行的应用和有用的资源: