Cairngorm框架中的Chained Event - 如何实现事件序列
2008-11-04 21:40
513 查看
最近在学习Cairngorm框架,并且在Marcus的指导下,利用该框架来完成一个很小的应用(只有一页...)。
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;
}
2.所有要加入序列的事件,都继承自ChainEvent类,初始化这些事件,并使每个事件对象中的nextChainEvent变量保存有下一个事件的对象。
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 );
}
参考: 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;
}
2.所有要加入序列的事件,都继承自ChainEvent类,初始化这些事件,并使每个事件对象中的nextChainEvent变量保存有下一个事件的对象。
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 );
}
参考: http://undefined-type.com/index.php/2008/08/07/cairngorm-chain-events (提供了ChainEvent的主要框架,个人添加了退出事件序列的机制 :P)
相关文章推荐
- Android 框架学习2:源码分析 EventBus 3.0 如何实现事件总线
- 基于事件驱动的领域模型实现框架 - 分析框架如何解决各种典型业务逻辑场景
- CodeSharp.EventSourcing框架介绍-如何实现异步事件订阅
- 基于事件驱动的领域模型实现框架 - 分析框架如何解决各种典型业务逻辑场景
- WPF“动画序列”框架的初步研究与实现(附源码)
- Android中免Root实现Hook的Dexposed框架实现原理解析以及如何实现应用的热修复
- jquery中如何实现按回车触发按钮事件
- 请教如何实现listview长按事件后改变点击事件
- 在框架中,如何实现退出全部界面方法
- 【Unity3D】【NGUI】如何使用新的Event事件
- 深入解析PHP的Laravel框架中的event事件操作
- Android滑动菜单框架完全解析,教你如何一分钟实现滑动菜单特效
- js鼠标事件解析——如何用js实现一个拖动但是不触发其点击事件
- 如何用phototype框架实现一个简单的ajax验证
- recovery中event 事件实现
- 如何让超出父视图区域的子视图实现点击事件
- 如何实现基于框架的书籍交易网站的质量属性
- 如何实现手机app制作,常用开源框架汇总
- HTML--如何实现通过鼠标事件拖动页面图像(代码)
- 关于事件处理的完整框架Event,delegate,event args,无图有真相。