最近在学习Cairngorm框架,并且在Marcus的指导下,利用该框架来完成一个很小的应用(只有一页...)。
Cairngorm下的事件具有异步的特性,比如说,触发10个事件(CairngormEvent),每个事件去调用不同的Server端,并返回XML结构的结果。如果依次触发这10个事件,返回结果的时候,并不一定会是按触发的顺序来分别返回结果的。
事件异步的特性使得数据的取得更灵活,但是也有它的缺点。比如下面的情况:有一系列事件,调用相同的HTTPService服务,通过传递参数的不同,来实现相近的服务器端操作(我在做的是在服务器端,根据JSP数据生成静态的 HTML页面...)。这一系列事件的触发,如果使用普通的Cairngorm的事件机制,则没有办法在事件序列执行过程中,退出序列。因为你并不能确定什么事件已经触发而什么事件还没触发。所以,需要引入Chained Event
主要步骤:
1.自定义一个ChainEvent,继承CairngormEvent。定义一个变量nextChainEvent,以保存下一个Event的对象。
2.所有要加入序列的事件,都继承自ChainEvent类,初始化这些事件,并使每个事件对象中的nextChainEvent变量保存有下一个事件的对象。
3.自定义的Command类要继承SequenceCommand。在处理HTTPService返回值的方法里,首先判断一个保存在 ModelLoacator里的标志位(abortProcess),abortProcess等于true则把下一个事件对象付给nextEvent,然后调用executeNextCommand()。
4.使用异步机制事件来修改标志位(abortProcess)。
5.调用代码示例
参考: http://undefined-type.com/index.php/2008/08/07/cairngorm-chain-events (提供了ChainEvent的主要框架,个人添加了退出事件序列的机制 :P)
Cairngorm下的事件具有异步的特性,比如说,触发10个事件(CairngormEvent),每个事件去调用不同的Server端,并返回XML结构的结果。如果依次触发这10个事件,返回结果的时候,并不一定会是按触发的顺序来分别返回结果的。
事件异步的特性使得数据的取得更灵活,但是也有它的缺点。比如下面的情况:有一系列事件,调用相同的HTTPService服务,通过传递参数的不同,来实现相近的服务器端操作(我在做的是在服务器端,根据JSP数据生成静态的 HTML页面...)。这一系列事件的触发,如果使用普通的Cairngorm的事件机制,则没有办法在事件序列执行过程中,退出序列。因为你并不能确定什么事件已经触发而什么事件还没触发。所以,需要引入Chained Event
主要步骤:
1.自定义一个ChainEvent,继承CairngormEvent。定义一个变量nextChainEvent,以保存下一个Event的对象。
- public class ChainEvent extends CairngormEvent
- {
- public function ChainEvent( type:String )
- {
- super( type );
- }
- public var nextChainedEvent:ChainEvent;
- }
- public class EventChainFactory
- {
- public static function chainEvents( evts:Array ):ChainEvent
- {
- var len:int = evts.length;
- if ( len < 1 )
- return null;
- var returnEvent:ChainEvent = evts[ 0 ] as ChainEvent;
- var i:int = len-1;
- for ( i; i>=0; i-- )
- {
- if ( i != ( len-1 ) )
- {
- var e:ChainEvent = evts[ i ] as ChainEvent;
- var next_e:ChainEvent = evts[ i+1 ] as ChainEvent;
- e.nextChainedEvent = next_e;
- }
- }
- return returnEvent;
- }
- }
3.自定义的Command类要继承SequenceCommand。在处理HTTPService返回值的方法里,首先判断一个保存在 ModelLoacator里的标志位(abortProcess),abortProcess等于true则把下一个事件对象付给nextEvent,然后调用executeNextCommand()。
- public class ExecuteBulkGenerationCommand extends SequenceCommand implements ICommand {
- private var __model:StaticContentGenModel = StaticContentGenModel.getInstance();
- private var __section:SectionVO = null;
- private var __event:CairngormEvent = null;
- override public function execute(event:CairngormEvent):void {
- var responder:Responder = new Responder(onResult_processDone, onFault);
- __section = ( event as ExecuteBulkGenerationEvent ).section;
- __event = event;
- var delegate:ExecuteBulkGenerationDelegate = new ExecuteBulkGenerationDelegate( responder );
- delegate.staticContentGen( __section );
- }
- public function onResult_processDone( event:ResultEvent ):void {
- // event结果返回XML结构数据
- var path:String = event.result.result.path;
- var errorMsg:String = event.result.result.errorMessage;
- var processDone:Boolean = event.result.result.success as Boolean;
-
- __model.results.addItem( path );
-
- // 判断全局标志位, 触发下一个序列中的事件
- if( !__model.abortGeneration ) {
- nextEvent = ChainEvent( __event ).nextChainedEvent;
- this.executeNextCommand();
- }
- }
- public function onFault( event:Event ):void {
- __model.results.addItem( "Fault on ExecuteBulkGenerationCommand. Section : " +
- __section.section + " ; Mode : " + __section.generationMode );
- trace("Fault on ExecuteBulkGenerationCommand: " + event.toString());
- }
- }
4.使用异步机制事件来修改标志位(abortProcess)。
5.调用代码示例
- private function build():void
- {
- // TestAEvent,TestBEvent均继承自ChainEvent,见步骤1
- var chain : ChainEvent = EventChainFactory.chainEvents([
- new TestAEvent(), new TestBEvent()]);
- cgDispatcher.dispatchEvent( chain );
- }