[转载]Flex Cairngorm入门例子 – 宅男Johnny – 博客园.
我们按一个完整的Cairngorm流程来介绍这个例子。这个例子很简单,一个按钮和一个标签,当按钮点下之后标签上的数字开始递增。首先,我们需要一个页面,也就是Cairngorm中的View部分:
01 |
<?xml version= "1.0" encoding= "utf-8" ?> |
05 |
<span style= "color: rgb(255, 0, 0);" >xmlns:model= "model.*" xmlns:control= "control.*" xmlns:business= "business.*" </span> |
06 |
creationComplete= "application1_creationCompleteHandler(event)" > |
09 |
import com.adobe.cairngorm.control.CairngormEventDispatcher; |
10 |
import control.CountEvent; |
11 |
import control.MyFrontControl; |
12 |
import flash.utils.setTimeout; |
13 |
import model.MyModelLocator; |
14 |
import mx.events.FlexEvent; |
17 |
private function loggingHandler(evt:MouseEvent):void |
19 |
var num:Num = new Num(); |
20 |
num.startNum = MyModelLocator.getInstance().count; |
21 |
var countEvent:CountEvent = new CountEvent(num); |
22 |
<span style= "color: rgb(255, 0, 0);" >CairngormEventDispatcher.getInstance().dispatchEvent(countEvent);</span> |
25 |
protected function application 1 _creationCompleteHandler(event:FlexEvent):void |
32 |
<span style= "color: rgb(255, 0, 0);" ><fx:Declarations> |
33 |
<control:MyFrontControl/> |
34 |
<business:MyServiceLocator/> |
35 |
</fx:Declarations></span> |
36 |
<s:Label id= "lable" x= "430" y= "158" width= "66" height= "22" text= "{<span style=" color : rgb ( 255 , 0 , 0 ); ">MyModelLocator.getInstance().count</span>}" /> |
37 |
<s:Button id= "button" x= "430" y= "201" label= "start" width= "66" click= "loggingHandler(event)" /> |
当用户点击按钮之后,就会调用loggingHandler函数。这loggingHandler中声明了一个自定义Event——CountEvent。
03 |
import com.adobe.cairngorm.control.CairngormEvent; |
07 |
public class CountEvent <span style= "color: rgb(255, 0, 0);" >extends CairngormEvent</span> |
09 |
public var num:Num = new Num(); |
10 |
public function CountEvent(num:Num) |
12 |
super (MyFrontControl.COUNT_EVENT); |
CountEvent的构造函数中有一句super(MyFrontControl.COUNT_EVENT),在上一篇中我们讲到 FrontControl的作用是监听所有Event,其中COUNT_EVENT就是我们所定义的Event的type,记 住,CairngormEvent也是继承自Event的。当然,COUNT_EVENT不是凭空产生的,是我们在自定义的FrontControl中定 义的。自定义的FrontControl代码如下:
03 |
import com.adobe.cairngorm.control.FrontController; |
04 |
import command.CountCommand; |
06 |
public class MyFrontControl extends FrontController |
08 |
public static var COUNT_EVENT:String = "counting" ; |
09 |
public function MyFrontControl() |
11 |
this.addCommand(COUNT_EVENT,CountCommand); |
FrontControl管理所有的Event,监听它们并且接受处理它们,回想一下Observer Pattern,我们会在把所有的Observer对象存入Subject中,当事件发生之后Subject会在其内部的表中查找相应的Observer 然后调用它们的notify方法。你可以用相同的方法去理解FrontControl的机制,试想,如果我有两个Event,那么 FrontControl就应该这样写了:
03 |
import com.adobe.cairngorm.control.FrontController; |
05 |
import command.CountCommand; |
06 |
import command.CountCommand 2 ; |
08 |
public class MyFrontControl extends FrontController |
10 |
public static var COUNT_EVENT:String = "counting" ; |
11 |
public static var COUNT_EVENT 2: String = "counting2" ; |
12 |
public function MyFrontControl() |
14 |
this.addCommand(COUNT_EVENT,CountCommand); |
15 |
this.addCommand(COUNT_EVENT 2 ,CountCommand 2 ); |
FrontControl相当于一个Subject的实例,它把所有需要监听的Event和其对应的Command名称加入到内部的列表,并且 对所有的Event进行监听,当接受的Event之后它就会在内部列表中查找这个Event然后调用相应的Command类的execute()方法。
现在我们就可以很好地理解 CairngormEventDispatcher.getInstance().dispatchEvent(countEvent)这句话 了,Event被发送之后FrontControl处理之,现在我们来看FrontControl调用的Command是什么样的。
03 |
import business.CountDelegate; |
04 |
import com.adobe.cairngorm.commands.ICommand; |
05 |
import com.adobe.cairngorm.control.CairngormEvent; |
06 |
import control.CountEvent; |
07 |
import model.MyModelLocator; |
08 |
import mx.rpc.IResponder; |
09 |
import mx.rpc.events.ResultEvent; |
12 |
public class CountCommand <span style= "color: rgb(255, 0, 0);" >implements ICommand, IResponder</span> |
14 |
public function CountCommand(){ |
17 |
public function <span style= "color: rgb(255, 0, 0);" >execute</span>(event:CairngormEvent):void |
19 |
<span style= "color: rgb(255, 0, 0);" >var delegate:CountDelegate = new CountDelegate(this);</span> |
20 |
var countEvent:CountEvent = CountEvent(event); |
21 |
delegate.count(countEvent.num); |
23 |
public function <span style= "color: rgb(255, 0, 0);" >result</span>(data:Object):void |
25 |
var result:Num = data as Num; |
26 |
MyModelLocator.getInstance().num = result; |
27 |
MyModelLocator.getInstance().count = result.startNum; |
29 |
public function <span style= "color: rgb(255, 0, 0);" >fault</span>(info:Object):void |
我们看到了execute()方法,其实这个方法在接口ICommand中定义。在execute()方法中,Delegate被声明,并且相 应的方法被调用。result()方法同样需引起注意,因为它决定了Delegate调用远程服务之后如何处理结果。记住,result()方法是在 Delegate中调用的。fault()方法和result()一样,它们都在接口IResponder中定义。
我们接着说自定义的Delegate
03 |
import com.adobe.cairngorm.business.ServiceLocator; |
04 |
import flash.utils.clearTimeout; |
05 |
import flash.utils.setTimeout; |
06 |
import mx.rpc.IResponder; |
07 |
import mx.rpc.events.ResultEvent; |
08 |
import mx.rpc.remoting.RemoteObject; |
11 |
public class CountDelegate |
13 |
private var responder:IResponder; |
14 |
private var counter:int; |
15 |
private var remoteObject:RemoteObject; |
16 |
public function CountDelegate(responder:IResponder) |
18 |
this.responder = responder; |
20 |
public function count(num:Num):void |
22 |
counter = num.startNum; |
23 |
<span style= "color: rgb(255, 0, 0);" >remoteObject = ServiceLocator.getInstance().getRemoteObject( "counting" ); |
24 |
remoteObject.addEventListener(ResultEvent.RESULT,OnResult);</span> |
27 |
private function counting():void |
29 |
remoteObject.getOperation( "count" ).send( counter ); |
30 |
flash.utils.setTimeout(counting, 1000 ); |
32 |
private function OnResult(evt:ResultEvent):void |
34 |
var result:Num = new Num(); |
35 |
counter = evt.result as int; |
36 |
result.startNum = counter ; |
37 |
<span style= "color: rgb(255, 0, 0);" >responder.result(result);</span> |
这里我们以一个RemoteObject远程调用为例,首先,我们调用的远程服务在ServiceLocator中定义,可以通过 remoteObject = ServiceLocator.getInstance().getRemoteObject(“counting”)来制定这个远程对 象,”counting”是在ServiceLocator中定义的RemoteObject id(当然这个ServiceLocator也是我们自定义的,Cairngorm提供的ServiceLocator是一个单例模式的对象)。然后我们 为这个远程对象添加ResultEvent的监听器。当我们收到远程调用的结果时,我们调用responder.result()执行在Command中 实现的结果处理方法。
下面是我们自定义的ServiceLocator:
1 |
<?xml version= "1.0" encoding= "utf-8" ?> |
5 |
xmlns:cairngorm= "com.adobe.cairngorm.business.*" > |
7 |
<s:RemoteObject id= "counting" destination= "countingService" /> |
9 |
</cairngorm:ServiceLocator> |
RemoteObject和Blazeds的配置就不解释了,再附上我们自定义的VO和JAVA服务端代码就完整了。
3 |
import com.adobe.cairngorm.vo.IValueObject; |
4 |
public class Num implements IValueObject |
6 |
public var startNum:int; |
JAVA服务端代码
3 |
public class CountingService { |
4 |
public CountingService(){} |
5 |
public int count(int num){ |