pureMVC

    网络上目前流行的flex框架不少,包括地位资深出身名门的cariagorm ,当前走红的PureMVC,轻盈小巧的Model-Glue,Foundry ,ARP等。权衡了下利弊,选择了PureMVC。 主要因为PureMVC扩展性顶好,并且它与语言无关。

     由于是hello word,个人懒得写例子,所以采用的是网上某位同僚的例子,略加改进,如图,点击上一张/下一张切换图片。例子很简单,没必要用框架。但主要为了学习框架。
pureMVC
目录的架构介绍如下:

pureMVC

整个框架运作可以看作订单流程如图:

pureMVC
根据AVM的执行顺序,来介绍整个框架的运转:
首先运行HelloPureMVC.xml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
 creationComplete="initApp()"
 xmlns:component="component.*" 
 fontSize="12"> 
  <mx:Script>
   <![CDATA[
    
    import MyApp.MyAppFacade;
    public function initApp():void{
     var facade:MyAppFacade = MyAppFacade.getInstance();
     facade.startup( this );
    }
   ]]>
  </mx:Script>
 <mx:Box id="mainContainer" width="202" height="250">
 <component:Mydisplay id="display" width="200" height="200"/>
 <component:MyControlBar id="controlBar" x="0" y="200" height="50" width="200" />
 </mx:Box>
</mx:Application>


这个界面很简单,在一个BOX组件中添加2个自制组件,这两个自制组件Mydisplay和MyControlBar,在启动该应用时,加载initApp方法,获得MyAppFacade实例,启动pureMVC框架。下面便是2个组件的代码:

Mydisplay.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">
 <mx:Label id="nameLabel"/>
 <mx:Image id="image" y="30"/>
</mx:VBox>

MyControlBar.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:ControlBar xmlns:mx="http://www.adobe.com/2006/mxml">
 <mx:Button label="上一张" fontSize="12" id="btnPrev"/>
 <mx:Button label="下一张" fontSize="12" id="btnNext"/>
</mx:ControlBar>

MyAppFacade.as就是流图中的接单者,总裁。该角色继承了Facade ,实现了IFacade,可以说是有权有势。

package myApp
{
 import myApp.controller.GetUrlListCommand;
 import myApp.controller.StartupCommand;
 import org.puremvc.as3.interfaces.IFacade;
 import org.puremvc.as3.patterns.facade.Facade;

 /**
  * 该类作为框架的掌控者,它所做的事情主要包括:
  *      1.提供获取自身实例的getInstance()静态方法
  *      2.initializeController()初始化Controller控制器
  *             建立Notification与Command映射
  *      在该例子中建立了程序启动,Puremvc启动结束的command映射
  *      3.startup(obt:Object)该方法提供给界面调用,启动pureMVC
  *      4.运行顺序为:initializeController()->getInstance()->startup(app:Object)
  * */
  
 public class MyAppFacade extends Facade implements IFacade
 {
  //建立两个常量信息,用于广播
  public static const APP_STARTUP:String = "app_startup";
  public static const APP_STARTUP_OVER:String = "app_startup_over";
  
  public function MyAppFacade(){
   super();
  }
  
  public static function getInstance():MyAppFacade{
   if(instance==null) instance = new MyAppFacade();
   trace("getInstance()");
   return instance as MyAppFacade;
  } 
          
  override protected function initializeController():void{
   trace("initializeController()");
   super.initializeController();
   //register some Commands
   registerCommand(APP_STARTUP,StartupCommand);
   registerCommand(APP_STARTUP_OVER,GetUrlListCommand);
  }
  
  public function startup(app:Object):void{ 
   trace("startup(app:Object)");
   sendNotification(APP_STARTUP,app); 
  } 
  
 }
}

它任命了StartupCommand为总经理,StartupCommand继承了MacroCommand ,能够对下层经理发命令。这里下层的经理包括ModelPrepCommand和ViewPrepCommand

package myApp.controller{
 import org.puremvc.as3.patterns.command.MacroCommand;
 /**
  * 
  *  该类继承了MacroCommand将会在单例modelController和viewsController启动前调用
  *  当该类加载时执行初始化方法,initializeMacroCommand(),该方法中初始化2个控制器,初
  *  始化的顺序按照代码的书写顺序.
  * 
  * 
  * **/
 public class StartupCommand extends MacroCommand {
  // 程序开始时执行的 MacroCommand. 
  public function StartupCommand() {
   return;
  }
   //添加子Command 初始化 MacroCommand. 
  override protected function initializeMacroCommand():void {
   //以下两个命令按先进先出顺序执行;
   trace("initializeMacroCommand()");
   addSubCommand(ModelPrepCommand);
   addSubCommand(ViewPrepCommand);
   return;
  }
 }
}

ModelPrepCommand是管理model层的经理,也就是生产者经理。所有的材料,用品都要由这个部门负责。但ModelPrepCommand管理的是主管ImageUrlListProxy。

package myApp.controller{
 import myapp.model.*;
 import org.puremvc.as3.interfaces.ICommand;
 import org.puremvc.as3.interfaces.INotification;
 import org.puremvc.as3.patterns.command.SimpleCommand;
 import myApp.model.ImageUrlListProxy;


 /**
  * 
  * ModelPrepCommand作为系统的model控制器,管理了所有的model对象,model在整个pureMVC中起到了
  * 与数据交互的作用.这里需要注册一个proxy.该proxy的注册方式:
  *    facede获取proxy对象参数传递给proxy类对象,该类对象会将该proxy对象放置数组中,在系统调用 
  *    retrieveProxy的时候,将获得该proxy实例.
  * 
  * 
  * **/
 public class ModelPrepCommand extends SimpleCommand implements ICommand {

  public function ModelPrepCommand() {
   return;
  }
  //注册代理(proxy)
  public override  function execute(sender:INotification):void {
   trace("ModelPrepCommand");
   facade.registerProxy( new ImageUrlListProxy(ImageUrlListProxy.NAME) );
  }
 }
}

主管ImageUrlListProxy就叫A准备生产A货物,B准备调用B材料。这里是在xml中,调用数据。但是还没收到上级的命令,他们没有调用数据的。XML数据如下:

**************************************

<persons>
<person name="卡莫" source="pic/km.jpg"/>
<person name="李时珍" source="pic/lsz.jpg"/>
<person name="姚明" source="pic/ym.jpg"/>
<person name="费德勒" source="pic/fdl.jpg"/>
<person name="伍兹" source="pic/wz.jpg"/>
<person name="科比" source="pic/kb.jpg"/>
</persons>

**************************************

package myApp.model
{
 import myApp.model.vo.ImageUrlVO;
 
 import mx.controls.Alert;
 import mx.rpc.events.FaultEvent;
 import mx.rpc.events.ResultEvent;
 import mx.rpc.http.HTTPService;
 
 import org.puremvc.as3.interfaces.IProxy;
 import org.puremvc.as3.patterns.proxy.Proxy;
 /**
  * 
  * 该类用作获得数据,还提供了一个loadUrlList方法.
  * 
  * **/
 public class ImageUrlListProxy extends Proxy implements IProxy
 {
  public static const NAME:String = "ImageUrlListProxy";
  private var hs:HTTPService;
  
  //定义一些Notification字符常量
  public static const URL_LOAD_COMPLETE:String = "url_load_complete";
  
  public function ImageUrlListProxy(proxyName:String=null, data:Object=null)
  { 
   trace("ImageUrlListProxy(proxyName:String=null, data:Object=null)");
   super(proxyName,data);
   hs = new HTTPService();

   hs.addEventListener(ResultEvent.RESULT,onResult);
   hs.addEventListener(FaultEvent.FAULT,fault);
   
  } 
   
  public function loadUrlList():void{   
   hs.url = "xml/person.xml";
   hs.resultFormat ="e4x";
   hs.send();
   
  }
  public function fault(event:FaultEvent):void{
   trace(event.message);
  }   
  
  public function onResult(event:ResultEvent):void{
    data = new Array();

    var personList:XML = event.result as XML;
    
    for each(var p:XML in personList.person){
    var personName:String = p.@name;
    var personPic:String = p.@source;
    data.push(new ImageUrlVO(personPic,personName));  
    }
    if(data==null)Alert.show("数据为空");
    sendNotification( URL_LOAD_COMPLETE,data );
  }
 }
}

*********调用的材料*********

package myApp.model.vo
{
 public class ImageUrlVO
 {
  public var url:String;
  public var name:String;
  public function ImageUrlVO(url:String,name:String){
   this.url = url;
   this.name = name;
  }
 }
}

*********调用的材料*********

下层经理ViewPrepCommand在ModelPrepCommand做完后,立马开工,招来发货主管ImageMediator,ControlBtnsMediator把订货单列出

《var app:HelloPureMVC = notification.getBody() as HelloPureMVC;》

HelloPureMVC需要这些东西,你们开始准备吧。(生产者ModelPrepCommand不需要知道货是谁要的,只管生产)

package myApp.controller{
 import org.puremvc.as3.interfaces.ICommand;
 import org.puremvc.as3.interfaces.INotification;
 import org.puremvc.as3.patterns.command.SimpleCommand;
 import myApp.view.ImageMediator; 
 import myApp.MyAppFacade; 
 import myApp.view.ControlBtnsMediator;

 public class ViewPrepCommand extends SimpleCommand implements ICommand {

  public function ViewPrepCommand() {
   return;
  }
  // 创建 Mediator, 并把它们注册到View;   
  public override  function execute(notification:INotification):void {
   //得到载体
   var app:HelloPureMVC = notification.getBody() as HelloPureMVC;
   trace("ViewPrepCommand");
   //注册ImageMediator和ControlBtnsMediator
   facade.registerMediator( new ImageMediator(app.display) );
   facade.registerMediator( new ControlBtnsMediator(app.controlBar) );
   
   //通知已经初始化完毕
   sendNotification(MyAppFacade.APP_STARTUP_OVER,app);  
  }
 }
}

ImageMediator主管首当其冲,弄清自己的任务艰巨(显示图片,显示名字,在点击按钮后作出反应),分清主次先super(NAME, viewComponent);再让专门请了个人去监听广播listNotificationInterests,得到信号组(可自己看框架源码)后,handleNotification,组成专案组,完成各自的任务。

package myApp.view
{
 import myApp.model.ImageUrlListProxy;
 import myApp.model.vo.ImageUrlVO;
 
 import component.MyControlBar;
 
 import mx.controls.Alert;
 import mx.controls.Button;
 import mx.controls.Image;
 import mx.controls.Label;
 
 import org.puremvc.as3.interfaces.IMediator;
 import org.puremvc.as3.interfaces.INotification;
 import org.puremvc.as3.patterns.mediator.Mediator;

 public class ImageMediator extends Mediator implements IMediator
 {
  public static const NAME:String = "ImageMediator";
  
  private var arrayOfImage:Array=null; 
  private var currentIndex:int=-1;
  
  public function ImageMediator(viewComponent:Object)
  {
   trace("ImageMediator");
   super(NAME, viewComponent);
  }
  
  
  override public function listNotificationInterests():Array{
   //列出感兴趣的Notification
   trace("listNotificationInterests()");
   return [
     ImageUrlListProxy.URL_LOAD_COMPLETE,
     ControlBtnsMediator.NEXT_IMAGE,
     ControlBtnsMediator.PREV_IMAGE  
   ];

  } 
  
  override public function handleNotification(notification:INotification):void{ 
   trace("handleNotification(notification:INotification)");  
   switch(notification.getName()){
    case ImageUrlListProxy.URL_LOAD_COMPLETE:  
     arrayOfImage = notification.getBody() as Array;   
     if(arrayOfImage){
      (viewComponent.nameLabel as Label).text = (arrayOfImage[0] as ImageUrlVO).name;
      (viewComponent.image as Image).source = (arrayOfImage[0] as ImageUrlVO).url;
      currentIndex = 0;
     }else{
      Alert.show("没有得到图片链接","错误");
     }
     
    break; 
    case ControlBtnsMediator.NEXT_IMAGE:
        if(currentIndex==-1)break;
        if(currentIndex >= arrayOfImage.length-1 ){Alert.show("目前是最后一张图片","警告");}
        else{
         (viewComponent.nameLabel as Label).text = (arrayOfImage[currentIndex+1] as ImageUrlVO).name;
      (viewComponent.image as Image).source = (arrayOfImage[currentIndex+1] as ImageUrlVO).url;
      currentIndex++;
        }        
    break;
    case ControlBtnsMediator.PREV_IMAGE:
    if(currentIndex==-1)break;
    if(currentIndex <=0 ){Alert.show("目前是第一张图片","警告");}
        else{
         (viewComponent.nameLabel as Label).text = (arrayOfImage[currentIndex+-1] as ImageUrlVO).name;
      (viewComponent.image as Image).source = (arrayOfImage[currentIndex-1] as ImageUrlVO).url;
      currentIndex--;
        }
    break;   
    default:break;
   }   
  }     
 }
}

ControlBtnsMediator主管比较闲,主要负责看看是不是有人按了按钮就行。如果有人按了按钮,就发广播通知各单位:按了按钮,按了那个按钮。

package myApp.view
{
 import flash.events.MouseEvent;
 
 import mx.controls.Button;
 
 import org.puremvc.as3.interfaces.IMediator;
 import org.puremvc.as3.patterns.mediator.Mediator;

 public class ControlBtnsMediator extends Mediator implements IMediator
 {
  public static const NAME:String = "ControlBtnsMediator";
  
  public static const NEXT_IMAGE:String = "next_image";
  public static const PREV_IMAGE:String = "prev_image";
  
  public function ControlBtnsMediator(viewComponent:Object)
  {
   super(NAME, viewComponent);
   trace("ControlBtnsMediator");
   (viewComponent.btnPrev as Button).addEventListener(MouseEvent.CLICK,onClickPrev);
   (viewComponent.btnNext as Button).addEventListener(MouseEvent.CLICK,onClickNext);
  }  
  private function onClickPrev(e:MouseEvent):void{
   sendNotification(PREV_IMAGE);
  }
  private function onClickNext(e:MouseEvent):void{
   sendNotification(NEXT_IMAGE);
  }

 }
}

ViewPrepCommand经理在主管工作都准备好了后,就广播

sendNotification(MyAppFacade.APP_STARTUP_OVER,app); ,

总裁的秘书1号监听

registerCommand(APP_STARTUP_OVER,GetUrlListCommand);

去把货物提了出来

package myApp.controller
{
 import myApp.model.ImageUrlListProxy;
 import org.puremvc.as3.interfaces.ICommand;
 import org.puremvc.as3.interfaces.INotification;
 import org.puremvc.as3.patterns.command.SimpleCommand;

 public class GetUrlListCommand extends SimpleCommand implements ICommand
 {
  public function GetUrlListCommand()
  {
   super();
  }
  
  override public function execute(notification:INotification):void
  {
   //得到图片链接
   trace("GetUrlListCommand");
   (facade.retrieveProxy( ImageUrlListProxy.NAME ) as ImageUrlListProxy).loadUrlList();  
  }
 }
}

秘书在调完货后,发送广播,货物准备好了sendNotification( URL_LOAD_COMPLETE,data );,ImageMediator主管一直在监听,听到URL_LOAD_COMPLETE消息后,立马handleNotification,看看是什么消息,然后就执行里面对应的方法。采用的是switch case ,有效执行命令。

下面附有整个demo的例子以及pureMVC的源码.供大家下载.



你可能感兴趣的:(框架,xml,Flex,网络应用,Flash)