pureMVC的一些总结
发布时间:2020-12-15 01:11:07 所属栏目:百科 来源:网络整理
导读:这次项目中的框架用到了PureMVC,坦白的讲虽然用了,但并没有很明显的体会到 它给项目带来了些什么具体的、显而易见的优势,网上有说他能够摒弃flex自身繁杂的事件机制,能够开发模块化,等等之类的,确实有体现,但我并不认为这是它的优势, 因为这些flex本
这次项目中的框架用到了PureMVC,坦白的讲虽然用了,但并没有很明显的体会到 它给项目带来了些什么具体的、显而易见的优势,网上有说他能够摒弃flex自身繁杂的事件机制,能够开发模块化,等等之类的,确实有体现,但我并不认为这是它的优势, 因为这些flex本身完全可以做到这些,当然这很有可能是我的功力还不够,没有完全体会到pureMVC的力量之所在吧。 pureMVC 的具体架构以各部分的功能要点协同工作具体是怎么进行的,网上已经可以找到好多了,而且因为自己在项目中并没有很好的运用,我怕会误导大伙, 所以这部分内容大伙自己去看,去项目中体会吧,我在此只依据个人项目中运用pureMVC的经验谈谈应该注意的一些事项。 1.如果组件在多个地方被同时应用,需要注意mediator中事件派发; 场景:component A 和 B ?是同一个组件的两个不同实例, 分别在界面中的左右两个部分,怎样做到proxy中发出的事件, 组件component A 的mediator能监听而component B中监听不到; 解决方案:这一场景在普通的flex原生事件中并不存在任何困难,但在pureMVC中,因为统一组件的mediator原生状态下只会注册一次(mediator名字相同),而且proxy的事件名称因为相同,即使mediator被注册多次,因为里边的事件名称相同,所以当proxy派发事件时,component A 和 B 的mediator都可以监听得到。我们给每个mediator生成一个动态的名字 用以进行注册,并且将这个动态的名字关联到事件名称中,这样即使是同一个mediator,因为他们是以不同的名字注册,并以将这一事件名传递到proxy中,就很好的区分了事件派类型, code: Proxy; package com.natian.proxy { import flash.events.Event; import flash.utils.Dictionary; import mx.collections.ArrayCollection; import mx.controls.Alert; import mx.rpc.AbstractOperation; import mx.rpc.events.FaultEvent; import mx.rpc.events.ResultEvent; public class ResourceServiceProxy extends Proxy { public var NAME:String = "ResourceServiceProxy"; public var noti_get_node_tree:String = "getNodeTreeNoti"; //运用外部动态传入参数,使同一类型组件能注册多个mediator实例 public function ResourceServiceProxy(uuid:String) { //initName方法必须在调用父类构造函数之前 initName(uuid); super(NAME); } //动态构建mediator实例名和事件名称 private function initName(eid:String):void { NAME += eid; noti_get_node_tree += eid; } public function getNodeTree(node:TreeNode):void { var at:AbstractOperation = iinvoker.invokeMethod(GET_NODE_TREE,node); addAsyncListener(at,getNodeTreeOKHandler,getNodeTreeFailHandler); } private function getNodeTreeOKHandler(event:ResultEvent):void { var treeNode:TreeNode = event.result as TreeNode; if (treeNode == null) { EventManager.dispatchEvent(CommonEvent.EVENT_PROCESSBAR_REMOVE,null); return; } //派发的事件,将只会被相应mediator监听得到 sendNotification(noti_get_node_tree,treeNode); treeNode = null; //removeAsyncListener(event.target as AbstractOperation,getNodeTreeFailHandler); } private function getNodeTreeFailHandler(event:FaultEvent):void { //removeAsyncListener(event.target as AbstractOperation,getNodeTreeFailHandler); } } } Mediator: package com.natian.map { import com.natian.proxy.ResourceServiceProxy; import flash.utils.getQualifiedClassName; import mx.utils.UIDUtil; import org.puremvc.as3.interfaces.INotification; import org.puremvc.as3.patterns.mediator.Mediator; public class MyMapMediator extends Mediator { public var NAME:String = ?getQualifiedClassName(OpenScalesMapMediator)+ UIDUtil.createUID(); private var _proxy:ResourceServiceProxy; public function OpenScalesMapMediator(viewComponent:Object=null) { super(NAME,viewComponent); _controlView = viewComponent as MyMap; //获得 proxy实例,并且必须在构造函数中获得, _proxy = new ResourceServiceProxy(UIDUtil.createUID()); } //注册事件监听函数,晚于构造函数 override public function listNotificationInterests():Array { return [_proxy.noti_get_node_topology]; } override public function handleNotification(notification:INotification):void { var notiName:String = notification.getName(); switch(notiName){ case _proxy.noti_get_node_topology: // to do break; } } } } 2.清除mediator 场景:因为pureMVC中是以名字来注册mediator的,而我们某些时候,实例化了多个view,但通过mediator获得的view实例很可能是最早注册view,因此我们需要及时清除已经注册的mediator。 解决方案:pureMVC中对mediator的清除并没有直接提供方法,我们需要对ApplicationFacade进行改造,然后整个程序中运用ApplicationFacade进行mediator的注册 code: package com.natian.app { import flash.display.Sprite; import mx.modules.Module; import org.puremvc.as3.interfaces.IMediator; import org.puremvc.as3.patterns.facade.Facade; /** * @author: Bryant */ public class ApplicationFacade extends Facade { public static const SATART_UP:String = "start_up"; public static var appView:Sprite; public static var topView:Module; private var mediators:Object = new Object(); public function ApplicationFacade(s:Sign) { super(); if(s == null){ throw ArgumentError("your argument is wrong."); } } public static function getInstance():ApplicationFacade { if(instance == null){ instance = new ApplicationFacade(new Sign()); } return ApplicationFacade(instance); } override protected function initializeController():void { super.initializeController(); }? //重载Facade的注册函数 override public function registerMediator( mediator:IMediator ):void { super.registerMediator(mediator); mediators[mediator.getMediatorName()] = mediator.getMediatorName(); } //重载facade的移除函数,如果要删除个别还可以自己再加一个方法,对mediators操作即可 override public function removeMediator( mediatorName:String ) : IMediator { delete mediators[mediatorName]; return super.removeMediator(mediatorName); } public function clearMediators():void { for(var name:String in mediators) { removeMediator(name); } } } } class Sign{ } 3.若需要考虑公用组件的很好的通用性,建议该类组件不要用puremvc,这样更灵活些; 4.proxy放在mediator中直接获得可能比在command中更加灵活些; 以上都是个人的一点小经验,纯属个人观点,如有错误之处,欢迎大家拍砖。 总的来说在项目初期,puremvc的架构确实还是比较清晰,特别地如果你是flex新手,你能很快的找到开发的套路,你只需要 按照模子往里边填写具体实现功能就ok;但是随着项目代码的越来越多,特别是如果系统比较大的话,你会发现后期代码中几乎 每个功能点都会有一个mediator,facade,proxy与view对应,有些时候加一个小小的功能都需要走这一样个流程,不免感觉繁琐与臃肿了许多 太不灵活了,就我个人的经验体会,如果是大项目的话,还是倾向于自己项目组内部构件一套MVC的适用于自己项目的框架。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |