以前用Cairngorm框架的时候,颇为惊讶,居然只有十几K的大小
难道很简单?
用了一段时间后,发现,其实做个MVC框架并不是很难(难在完善与通用)
自己也想搞点积累,就试着做了起来,打算搞个自己的MVC框架
要做这个首先要明白MVC是什么
M(模型):说白了,就是存储数据,操作数据的地方
V(视图):就是视图,负责呈现,数据绑定等
C(控制器):连接视图和模型的地方,在Flex中,就是做事件转发和监听增加的
除了上面的,还需要知道, 用了MVC会达到什么效果
简单的说,就是让数据存储,和数据操作 跟 视图呈现分离开
也就是让Module或者Application中,持有仅可能少的代码,把代码都放到AS类中
好,废话到这,下面是代码:
C层,控制器层:
package com.emavaj.mvc.control{ import mx.core.Application; /**. * 命令控制者,即为控制层MV(C) */ public class Controlor{ /**增加监听.*/ public static function addCommand(event:String, clazz:Class):void { /**clazz类是实现了com.emavaj.mvc.Command接口的类.*/ var temp:Object = new clazz(); /**将模型层接口中的doCommand方法加入监听.*/ if (temp.hasOwnProperty("doCommand")) { var fun:Function = temp["doCommand"]; Application.application.addEventListener(event,fun); } else { throw Error("增加监听:" + event + ",失败!"); } } /**增加监听,具体到函数.*/ public static function addCommandWithFunction(event:String, clazz:Class, fun:String):void { var temp:Object = new clazz(); if (temp.hasOwnProperty(fun)) { var theFunction:Function = temp[fun]; Application.application.addEventListener(event,theFunction); } else { throw Error("增加监听:" + event + ",失败!"); } } } }
我的思路是模仿Cairngorm框架的,
就是把
addEventListener
这个函数封装一次,把参数,从 事件标识 + 函数
改为了 事件标识 + 类
好处就是,让监听该事件的函数,不仅仅是监听函数调用的类的函数而已
比如:
主应用程序中调用增加监听Event.ADDED事件,那么对这个事件的响应函数,必须是主应用程序中的函数
(当然,如果你像上面那么做反射的话,也可以。其实我就是封装了一次)
下面是M层,模型层:
package com.emavaj.mvc.command{ /**. * 命令执行接口 */ public interface ICommand{ /**执行命令方法.*/ function doCommand(event:*):void; } }
这层,我仅提供了一个接口
也就是为 控制层服务的,当我再控制层利用反射 取得该类的函数时
我默认就制定 模型层中的接口 doCommand 方法为执行函数
(当然,我上面也提供了一个类中任意函数监听的方法)
也就是所,充当数据处理的AS类,只有实现ICommand接口,然后完成这个函数,就可以在增加监听的时候
传入处理类的类名
事件发生时,就会直接执行到doCommand方法
从而实现了逻辑的分离
下面是V层,视图层
package com.emavaj.mvc.view{ import mx.core.Application; import mx.modules.ModuleLoader; /**. * 视图工具 */ public class ViewUtil{ /**单例对象.*/ private static var viewUtil:ViewUtil; /**获取ModuelLoader.*/ public static function getModuleLoader(Id:String):ModuleLoader { var app:Object = Application.application; if (app.hasOwnProperty(Id)) { var property:ModuleLoader = app[Id]; return property; } else { throw Error("取得ModuleLoader失败,该应用程序没有ID为:" + Id + "的ModuleLoader"); } } /**获取Moduel.*/ public static function getModule(Id:String):Object { var app:Object = Application.application; if (app.hasOwnProperty(Id)) { var property:ModuleLoader = app[Id]; return property.child; } else { throw Error("取得Module失败,该应用程序没有ID为:" + Id + "的ModuleLoader"); } } /**获取组件,获取任意视图base中的视图Id组件.*/ public static function getView(base:Object, Id:String):Object { if (base.hasOwnProperty(Id)) { var property:Object = base[Id]; return property; } else { throw new Error("取得组件失败," + base + "视图中没有" + Id + "组件"); } } } }
明显看到,视图层和控制层都是伪类
视图层提供数据呈现的当然是控件或.MXML文件
这里的视图层只提供了视图的查找
也就是说,你使用ViewUtil中的静态方法
就可以在 程序很任意地方,AS类,或者任意Module,来获得任意视图、Module的引用
从而操作视图变化!
至此,MVC已经完成
同时我也提供了一些简单的服务获取
package com.emavaj.mvc.util{ import mx.core.Application; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; import mx.rpc.remoting.RemoteObject; /**. * 远程服务对象工具类 */ public class RemoteUtil{ /**取得远程调用对象.*/ public static function getRemoteById(Id:String):RemoteObject { return Application.application[Id]; } /**组成调用监听方法.*/ public static function addListener(remote:RemoteObject, success:Function, fault:Function):void { remote.addEventListener(ResultEvent.RESULT, success); remote.addEventListener(FaultEvent.FAULT, fault); } /**移除调用监听.*/ public static function removeListener(remote:RemoteObject, success:Function, fault:Function):void { remote.removeEventListener(ResultEvent.RESULT, success); remote.removeEventListener(FaultEvent.FAULT, fault); } } }
写出了一些Remote的常用方法,获取RemoteObject引用,增加监听,异常监听等
虽属于MVC范畴,但是作为框架,必定少不了
如果有什么意见或建议,欢迎留言,讨论
附件有源码和SWC文件
(SWC在源码的bin目录下,可以直接使用)