以前用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目录下,可以直接使用)