pureMVC的一些总结

来源:互联网 发布:seo推广工具 编辑:程序博客网 时间:2024/06/05 00:15
这次项目中的框架用到了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,getNodeTreeOKHandler,getNodeTreeFailHandler);
}

private function getNodeTreeFailHandler(event:FaultEvent):void {
//removeAsyncListener(event.target as AbstractOperation,getNodeTreeOKHandler,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的适用于自己项目的框架。
原创粉丝点击