日,刚写完结果没保存就出来,只能重写一遍,真是郁闷...................
最近在做一个flex的项目,用到了puremvc与pipe通信,这个框架是由之前一个已经走了的同事搭建的,我刚看的时候一片茫然,各种郁闷,没办法,还得研究 看了大概半个多月吧,多少有点心得,起码是这个框架可以跑起来了,呵呵
pipe是什么呐?以我的理解就是flex shell与module,module与module之间通信的方式,当你在加载某个module时建立管道 这样shell和你的module之间就可以通信了 一些理论的东西 我就不说了 大家可以自己找些资料看一下 我就把搭建pipe的流程说一下
首先我们需要建立一个类 来声明一些管道常量 这样可以避免我们写错 和清晰的理解它的意义
package com.hpcc.police.common
{
/**
* 存储shell和module共用的常量
* 这样就可以避免在编译shell的时候去应用module
*/
public class PipeAwareModuleConstants
{
// const
public static const SHELL_TO_MODULE_PIPE:String = 'shellToModulePipe';
public static const STDOUT:String = 'standardOutput';
public static const STDIN:String = 'standardInput';
public static const MODULE_TO_SHELL_PIPE:String = 'moduleToShellPipe';
public static const MODULE_TO_SHELL_MESSAGE: String = "moduleToShellMessage";
public static const SHELL_TO_MODULE_MESSAGE:String = 'shellToModuleMessage';
public static const MODULE_TO_MODULE_PIPE:String = 'moduleToModulePipe';
public function PipeAwareModuleConstants()
{
}
}
}
然后再shell的view层写一个Mediator文件 这个文件继承自JunctionMediator 我的文件名叫ShellJunctionMediator
我只把有用的代码 粘上来了 至于Mediator类的模板你随便下个就有了
直接看代码吧
这里我们需要声明一个object来保存建立的管道信息 这样你在删除管道的时候就可一根据名字来进行删除
private var outMap:Object = {};//这个就是保存管道信息的类
override public function handleNotification(note:INotification):void
{
var moduleID:String = String(note.getBody())
switch(note.getName())
{
case ApplicationFacade.MODULE_ADDED:
connectModule(note.getBody() as IPipeAwareModule);//在module加载完毕时创建管道连接
break;
case ApplicationFacade.DISCONNECT_MOUDLE_PIPE:
var junctionOut:TeeSplit = junction.retrievePipe(PipeAwareModuleConstants.STDOUT) as TeeSplit;
junctionOut.disconnectFitting(outMap[moduleID])//删除时你只需要删除主应用到module的就可以了
delete outMap[moduleID];
break;
default:
super.handleNotification(note);
break;
}
}
/**
* Connect the module using pipes and its TeeMerge and TeeSplit(用TeeMerge和TeeSplit以及管道连接Module)
*
* @param module Module typed as IPipeAwareModule(将Module转化成IPipeAwareModule)
*/
public function connectModule(module:IPipeAwareModule):void
{
// Register SHELL_TO_MODULE_PIPE from the shell to all modules(注册从主应用到所有Module的管道)
junction.registerPipe(PipeAwareModuleConstants.STDOUT,Junction.OUTPUT,new TeeSplit());
// Register MODULE_TO_SHELL_PIPE to the shell from all modules (注册从所有Module到主应用的管道)
junction.registerPipe(PipeAwareModuleConstants.STDIN,Junction.INPUT,new TeeMerge());
// add a pipe listener for messages sended by module(给Module发送的message添加管道监听)
junction.addPipeListener(PipeAwareModuleConstants.STDIN,this,handlePipeMessage);
// module -> shell(从module到主应用)
var moduleToShell:Pipe=new Pipe();
module.acceptOutputPipe(PipeAwareModuleConstants.MODULE_TO_SHELL_PIPE,moduleToShell);
var shellInFitting:TeeMerge=junction.retrievePipe(PipeAwareModuleConstants.STDIN) as TeeMerge;
shellInFitting.connectInput(moduleToShell);
//shell -> module(从主应用到module)
var shellToModule:Pipe=new Pipe();
module.acceptInputPipe(PipeAwareModuleConstants.STDOUT,shellToModule);
var shellOutFitting:TeeSplit=junction.retrievePipe(PipeAwareModuleConstants.STDOUT) as TeeSplit;
shellOutFitting.connect(shellToModule);
var moduleID:String = String(module)
outMap[moduleID] = shellToModule;
}
/**
* Handle incoming pipe messages for the ShellJunction.(处理传进来给ShellJunction的管道信息)
*
* @param message Message typed as IPipeMessage
*/
override public function handlePipeMessage(message:IPipeMessage):void
{
}
这样shell到module之间的管道已经建立了 下面我们还需要建立module到module之间的管道信息
还是直接代码吧
override public function handleNotification(note:INotification):void
{
var moduleID:String = String(note.getBody())
//var moduleFacade:IPipeAware = note.getBody() as IPipeAware
switch(note.getName())
{
case ApplicationFacade.MODULE_ADDED:
connectModule(note.getBody() as IPipeAwareModule);
break;
case ApplicationFacade.DISCONNECT_MODULE_TO_MODULE:
var junctionOut:TeeSplit = junction.retrievePipe(PipeAwareModuleConstants.STDIN) as TeeSplit;
junctionOut.disconnectFitting(outMap[moduleID])
delete outMap[moduleID];
break;
default:
super.handleNotification(note);
break;
}
}
/**
* Connect the module using pipes and its TeeMerge and TeeSplit(用TeeMerge和TeeSplit以及管道连接Module)
*
* @param module Module typed as IPipeAwareModule(将Module转化成IPipeAwareModule)
*/
public function connectModule(module:IPipeAwareModule):void
{
// Register SHELL_TO_MODULE_PIPE from the shell to all modules(注册从主应用到所有Module的管道)
junction.registerPipe(PipeAwareModuleConstants.STDIN,Junction.OUTPUT,new TeeSplit());
// Register MODULE_TO_MODULE_PIPE to the modules from all modules (注册从所有Module到Module的管道)
junction.registerPipe(PipeAwareModuleConstants.MODULE_TO_MODULE_PIPE,Junction.INPUT,new TeeMerge());
// add a pipe listener for messages sended by module(给Module发送的message添加管道监听)
junction.addPipeListener(PipeAwareModuleConstants.MODULE_TO_MODULE_PIPE,this,handlePipeMessage);
// module -> shell(从module到主应用)
var moduleToShellJunction:Pipe=new Pipe();
module.acceptOutputPipe(PipeAwareModuleConstants.MODULE_TO_MODULE_PIPE,moduleToShellJunction);
var shellInFitting:TeeMerge=junction.retrievePipe(PipeAwareModuleConstants.MODULE_TO_MODULE_PIPE) as TeeMerge;
shellInFitting.connectInput(moduleToShellJunction);
//shell -> module(从主应用到module)
var shellToModuleJunction:Pipe=new Pipe();
module.acceptInputPipe(PipeAwareModuleConstants.STDIN,shellToModuleJunction);
var shellOutFitting:TeeSplit=junction.retrievePipe(PipeAwareModuleConstants.STDIN) as TeeSplit;
shellOutFitting.connect(shellToModuleJunction);
var moduleID:String = String(module)
outMap[moduleID] = shellToModuleJunction;
}
/**
* Handle incoming pipe messages for the ShellJunction.(处理传进来给ShellJunction的管道信息)
*
* @param message Message typed as IPipeMessage
*/
//注意下这的处理管道信息方式与shell到module的不一样
override public function handlePipeMessage(message:IPipeMessage):void
{
var junctionOut:TeeSplit = junction.retrievePipe( PipeAwareModuleConstants.STDIN ) as TeeSplit;
junctionOut.write( message );
}
以上两个文件的是在shell的view层写的 下面改module的view层做些什么了
//至于为什么这么注册我不是特别明白,代码是例子的 但是好使 希望哪位了解的朋友指点下 不明白的你就这么写就行了 保证没问题的 哈哈
override public function onRegister():void
{
var teeMerge:TeeMerge = new TeeMerge();
junction.registerPipe( PipeAwareModuleConstants.STDIN, Junction.INPUT, teeMerge );
junction.addPipeListener( PipeAwareModuleConstants.STDIN, this, handlePipeMessage );
var teeSplit:TeeSplit = new TeeSplit();
junction.registerPipe( PipeAwareModuleConstants.MODULE_TO_MODULE_PIPE, Junction.OUTPUT, teeSplit );
}
override public function onRemove():void
{
}
override public function listNotificationInterests():Array
{
var interests:Array = super.listNotificationInterests();
return interests;
}
override public function handleNotification( note:INotification ):void
{
var pipe:IPipeFitting;
var type:String = note.getType() as String;
switch( note.getName() )
{
case JunctionMediator.ACCEPT_INPUT_PIPE:
{
/*
* Create a tee merge between accepted pipe and the
* existing module's STDIN pipe.
*/
if (type ==PipeAwareModuleConstants.STDIN)
{
pipe = note.getBody() as IPipeFitting;
var teeMerge:TeeMerge = junction.retrievePipe(PipeAwareModuleConstants.STDIN) as TeeMerge;
teeMerge.connectInput(pipe);
//It does not need to be handled by super.
return;
}
break;
}
/*
* Add an input pipe (special output handling for each new
* connected HelloModule).
*/
case JunctionMediator.ACCEPT_OUTPUT_PIPE:
{
/*
* Output splitting tee for HELLO_TO_HELLO pipes. We need
* to override super to handle this.
*/
if (type == PipeAwareModuleConstants.MODULE_TO_MODULE_PIPE)
{
pipe = note.getBody() as IPipeFitting;
var teeSplit:TeeSplit = junction.retrievePipe(PipeAwareModuleConstants.MODULE_TO_MODULE_PIPE) as TeeSplit;
teeSplit.connect( pipe );
//It does not need to be handled by super.
return;
}
break;
}
}
super.handleNotification(note);//这个地方大家一定要注意下 它是写在switch语句外面的 如果你写在里面了 shell到module的管道通信就没被注册 这个问题折磨了我好几天 呵呵 千万注意啊
好了 到这基本就算完事了 至于一些细节问题我就不赘述了 希望能给刚研究这个问题的朋友一些启发