[转载]Flex Cairngorm入门例子

[转载]Flex Cairngorm入门例子 – 宅男Johnny – 博客园.

我们按一个完整的Cairngorm流程来介绍这个例子。这个例子很简单,一个按钮和一个标签,当按钮点下之后标签上的数字开始递增。首先,我们需要一个页面,也就是Cairngorm中的View部分:

01 <?xml version="1.0" encoding="utf-8"?>
02 <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
04 xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
05 <span style="color: rgb(255, 0, 0);">xmlns:model="model.*" xmlns:control="control.*" xmlns:business="business.*"</span>
06 creationComplete="application1_creationCompleteHandler(event)">
07 <fx:Script>
08 <![CDATA[
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;
15 import vo.Num;
16
17 private function loggingHandler(evt:MouseEvent):void
18 {
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>
23 }
24
25 protected function application1_creationCompleteHandler(event:FlexEvent):void
26 {
27 lable.text = "0";
28 }
29
30 ]]>
31 </fx:Script>
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)"/>
38
39 </s:Application>

当用户点击按钮之后,就会调用loggingHandler函数。这loggingHandler中声明了一个自定义Event——CountEvent。

01 package control
02 {
03 import com.adobe.cairngorm.control.CairngormEvent;
04
05 import vo.Num;
06
07 public class CountEvent <span style="color: rgb(255, 0, 0);">extends CairngormEvent</span>
08 {
09 public var num:Num = new Num();
10 public function CountEvent(num:Num)
11 {
12 super(MyFrontControl.COUNT_EVENT);
13 this.num = num;
14 }
15 }
16 }

CountEvent的构造函数中有一句super(MyFrontControl.COUNT_EVENT),在上一篇中我们讲到 FrontControl的作用是监听所有Event,其中COUNT_EVENT就是我们所定义的Event的type,记 住,CairngormEvent也是继承自Event的。当然,COUNT_EVENT不是凭空产生的,是我们在自定义的FrontControl中定 义的。自定义的FrontControl代码如下:

01 package control
02 {
03 import com.adobe.cairngorm.control.FrontController;
04 import command.CountCommand;
05
06 public class MyFrontControl extends FrontController
07 {
08 public static var COUNT_EVENT:String = "counting";
09 public function MyFrontControl()
10 {
11 this.addCommand(COUNT_EVENT,CountCommand);
12 }
13 }
14 }

FrontControl管理所有的Event,监听它们并且接受处理它们,回想一下Observer Pattern,我们会在把所有的Observer对象存入Subject中,当事件发生之后Subject会在其内部的表中查找相应的Observer 然后调用它们的notify方法。你可以用相同的方法去理解FrontControl的机制,试想,如果我有两个Event,那么 FrontControl就应该这样写了:

01 package control
02 {
03 import com.adobe.cairngorm.control.FrontController;
04
05 import command.CountCommand;
06 import command.CountCommand2;
07
08 public class MyFrontControl extends FrontController
09 {
10 public static var COUNT_EVENT:String = "counting";
11 public static var COUNT_EVENT2:String = "counting2";
12 public function MyFrontControl()
13 {
14 this.addCommand(COUNT_EVENT,CountCommand);
15 this.addCommand(COUNT_EVENT2,CountCommand2);
16 }
17 }
18 }

FrontControl相当于一个Subject的实例,它把所有需要监听的Event和其对应的Command名称加入到内部的列表,并且 对所有的Event进行监听,当接受的Event之后它就会在内部列表中查找这个Event然后调用相应的Command类的execute()方法。

现在我们就可以很好地理解 CairngormEventDispatcher.getInstance().dispatchEvent(countEvent)这句话 了,Event被发送之后FrontControl处理之,现在我们来看FrontControl调用的Command是什么样的。

01 package command
02 {
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;
10 import vo.Num;
11
12 public class CountCommand <span style="color: rgb(255, 0, 0);">implements ICommand, IResponder</span>
13 {
14 public function CountCommand(){
15
16 }
17 public function <span style="color: rgb(255, 0, 0);">execute</span>(event:CairngormEvent):void
18 {
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);
22 }
23 public function <span style="color: rgb(255, 0, 0);">result</span>(data:Object):void
24 {
25 var result:Num = data as Num;
26 MyModelLocator.getInstance().num = result;
27 MyModelLocator.getInstance().count = result.startNum;
28 }
29 public function <span style="color: rgb(255, 0, 0);">fault</span>(info:Object):void
30 {
31 }
32 }
33 }

我们看到了execute()方法,其实这个方法在接口ICommand中定义。在execute()方法中,Delegate被声明,并且相 应的方法被调用。result()方法同样需引起注意,因为它决定了Delegate调用远程服务之后如何处理结果。记住,result()方法是在 Delegate中调用的。fault()方法和result()一样,它们都在接口IResponder中定义。

我们接着说自定义的Delegate

01 package business
02 {
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;
09 import vo.Num;
10
11 public class CountDelegate
12 {
13 private var responder:IResponder;
14 private var counter:int;
15 private var remoteObject:RemoteObject;
16 public function CountDelegate(responder:IResponder)
17 {
18 this.responder = responder;
19 }
20 public function count(num:Num):void
21 {
22 counter = num.startNum;
23 <span style="color: rgb(255, 0, 0);">remoteObject = ServiceLocator.getInstance().getRemoteObject("counting");
24 remoteObject.addEventListener(ResultEvent.RESULT,OnResult);</span>
25 counting();
26 }
27 private function counting():void
28 {
29 remoteObject.getOperation("count").send(counter);
30 flash.utils.setTimeout(counting, 1000);
31 }
32 private function OnResult(evt:ResultEvent):void
33 {
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>
38 }
39 }
40 }

这里我们以一个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"?>
2 <cairngorm:ServiceLocator xmlns:fx="http://ns.adobe.com/mxml/2009"
5 xmlns:cairngorm="com.adobe.cairngorm.business.*">
6 <fx:Declarations>
7 <s:RemoteObject id="counting" destination="countingService"/>
8 </fx:Declarations>
9 </cairngorm:ServiceLocator>

RemoteObject和Blazeds的配置就不解释了,再附上我们自定义的VO和JAVA服务端代码就完整了。

1 package vo
2 {
3 import com.adobe.cairngorm.vo.IValueObject;
4 public class Num implements IValueObject
5 {
6 public var startNum:int;
7 }
8 }

JAVA服务端代码

1 package cairngorm;
2
3 public class CountingService {
4 public CountingService(){}
5 public int count(int num){
6 return ++num;
7 }
8 }
赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏