中央管理-Flex Central Managerment

 

Flex Chaos-All-in-one这一节中所提到的,在大型项目中,将所有的代码放在一起并非明智之举,确切的讲:正确的方法是将商业逻辑层与UI层分离开来。

 

 

 

中央管理的理念是使用一个远程对象管理器来控制Flex与后端的通讯。其构建体系如下图所示

 

 

图中每一个UI组件都将调用一个服务(Service),服务类将调用中央管理器(Central Manager),中央管理器类将调用服务器端的解决方案。而图中全局对象管理器(Global Object Manager)将用来在UI之间传递数据。

现在来看看简单密友列表应用的实现。

首先是LoginView.xml

Xml代码
  1. <?xml version=”1.0″ encoding=”utf-8″?>  
  2. <mx:Panel xmlns:mx=”http://www.adobe.com/2006/mxml” layout=”absolute” width=”300″ height=”200″ horizontalAlign=”center” verticalAlign=”middle” title=”Flex Central Manager Login”>  
  3. <mx:Script>  
  4.  <![CDATA[ 
  5.   import com.ny.flex.centralManagement.service.LoginService; 
  6.   import mx.validators.Validator; 
  7.   import mx.containers.ViewStack; 
  8.   import mx.rpc.events.ResultEvent; 
  9.   private function login():void{ 
  10.    if(Validator.validateAll(validators).length == 0){ 
  11.     LoginService.getInstance().login(username.text,password.text); 
  12.    }   
  13.   } 
  14.  ]]>  
  15. </mx:Script>  
  16.  <!–  Validators–>  
  17.  <mx:Array id=”validators”>  
  18.     <mx:StringValidator  id=”userNameValidator” source=”{username}”  property=”text”  required=”true”/>  
  19.     <mx:StringValidator  id=”passwordValidator” source=”{password}”  property=”text” required=”true” />  
  20.  </mx:Array>     
  21. <mx:Form id=”loginForm” x=”0″ y=”0″>  
  22.           <mx:FormItem label=”Username:” >  
  23.                <mx:TextInput id=”username” />  
  24.            </mx:FormItem>  
  25.            <mx:FormItem label=”Password:” >  
  26.                <mx:TextInput id=”password” displayAsPassword=”true” />  
  27.            </mx:FormItem>  
  28.            <mx:FormItem direction=”horizontal” verticalGap=”15″ paddingTop=”5″ width=”170″>  
  29.                <mx:Button id=”loginBtn” label=”Login” click=”login()”/>  
  30.            </mx:FormItem>  
  31.     </mx:Form>  
  32.       
  33. </mx:Panel>  

 

 

其功能的核心是:


LoginService.getInstance().login(username.text,password.text); 

 

它的作用是有效的分离了商务逻辑层和视图组件。在此服务类程序不需支持任何状态,因此我们保持其单件模式(singleton)。

LoginService类文件如下:

 

Xml代码
  1. import com.ny.flex.centralManagement.event.DataManagerResultEvent;  
  2.  import com.ny.flex.centralManagement.manager.GlobalObjectManager;  
  3.  import com.ny.flex.centralManagement.manager.RemoteObjectManager;  
  4.    
  5.  public class LoginService  
  6.  {  
  7.   public var roManager:RemoteObjectManager = null;   
  8.   public var gom:GlobalObjectManager = GlobalObjectManager.getInstance();  
  9.   private static var _instance:LoginService =null;  
  10.     
  11.   public static function getInstance():LoginService{  
  12.    if(_instance == null){  
  13.     _instance =  new LoginService(new PrivateClass)  
  14.    }  
  15.    return _instance;  
  16.      
  17.   }  
  18.   public function LoginService(privateclass:PrivateClass)  
  19.   {  
  20.    if(LoginService._instance == null){  
  21.     LoginService._instance =  this;  
  22.    }  
  23.   }  
  24.   public function login(userName:String,password:String):void{  
  25.  roManager = RemoteObjectManager.getRemoteObjectManager(”flexmvcRO”);  
  26.    roManager.addEventListener(”getLoginUser”,loginHandler);  
  27.    var params:Array = new Array(userName,password);  
  28.      
  29.    roManager.makeRemoteCall(”getLoginUserName”,”getLoginUser”,params);  
  30.   }  
  31.   private function loginHandler(event:DataManagerResultEvent):void {  
  32.    var userName:String = event.result as String;  
  33.    if(userName){  
  34.     gom.loginUserName = userName;  
  35.     gom.viewStackSelectedIndex=1;  
  36.    }  
  37.   }  
  38.  }  

 

 

 

 代码中有两个特别的对象:

            RemoteObjectManager

            GlobalObjectManager

RemoteObjectManager是一个单件的类,用来实现中央管理所有的远程对象通讯。原始的代码来自于Jeff Tapper的博客:

Creating a Remote Object DataManager in ActionScript 3.0 for Flex 2.0

 

RemoteObjectManager.as:

Xml代码
  1. package com.ny.flex.centralManagement.manager  
  2. {  
  3.     import com.ny.flex.centralManagement.event.DataManagerResultEvent;  
  4.       
  5.     import flash.events.EventDispatcher;  
  6.       
  7.     import mx.core.Application;  
  8.     import mx.resources.ResourceManager;  
  9.     import mx.rpc.AbstractOperation;  
  10.     import mx.rpc.AsyncToken;  
  11.     import mx.rpc.events.FaultEvent;  
  12.     import mx.rpc.events.ResultEvent;  
  13.     import mx.rpc.remoting.mxml.RemoteObject;  
  14.       
  15.     public class RemoteObjectManager extends EventDispatcher {  
  16.         public var ro:RemoteObject;          
  17.         private var eventName:String;           
  18.           
  19.         private static var instanceMap:Object = new Object();      
  20.                
  21.         public function RemoteObjectManager(pri:PrivateClass,dest:String){              
  22.             this.ro = new RemoteObject();              
  23.             ro.destination = dest;  
  24.         }    
  25.                  
  26.         public static function getRemoteObjectManager(dest:String):RemoteObjectManager{  
  27.             if(RemoteObjectManager.instanceMap[dest] == null){                 
  28.                 RemoteObjectManager.instanceMap[dest] = new RemoteObjectManager(new PrivateClass(),dest);            
  29.             }            
  30.             var dm:RemoteObjectManager= RemoteObjectManager.instanceMap[dest];            
  31.             return dm;          
  32.         }  
  33.         public function makeRemoteCall(methodName:String,eventName:String,args:Array=null):void{  
  34.             this.eventName = eventName;              
  35.             var op:mx.rpc.AbstractOperation = ro[methodName];    
  36.             ro.addEventListener("result", doResults);              
  37.             ro.addEventListener("fault", doFault);      
  38.             var token:AsyncToken = null;          
  39.             if(args && args.length >0){                   
  40.                 token = op.send.apply(null,args);              
  41.             }    
  42.             else {  
  43.                 token = op.send();              
  44.             }   
  45.             token.eventName = eventName;         
  46.         }  
  47.         private function doResults(event:ResultEvent):void{               
  48.             var e:DataManagerResultEvent = new DataManagerResultEvent(event.token.eventName, event.result);   
  49.             this.dispatchEvent(e);          
  50.         }           
  51.         private function doFault(fault:FaultEvent):void{               
  52.             this.dispatchEvent(fault);           
  53.         }   
  54.              
  55.         public override function toString():String{               
  56.             return "RemoteObjectDataManager";           
  57.         }      
  58.      }  
  59. }  
  60.  /**   PrivateClass is used to make    DataManager constructor private  */     
  61.   class PrivateClass{  
  62.     public function PrivateClass() {}   
  63.   
  64.  }  

 

GlobalObjectManager”用来在UI之间传递信息,例如,我们使用ViewStackselectedIndex来决定显示ViewStack中的哪一个视图,则使用全局对象viewStackSelectedIndex ,其代码如下面的黑体部分:

Xml代码
  1. <?xml version=”1.0″ encoding=”utf-8″?>  
  2. <mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml“  xmlns:views=”com.ny.flex.centralManagement.views.*” layout=”absolute”  width=”100%” height=”100%”>  
  3. <mx:Script>  
  4.  <![CDATA[ 
  5.   import mx.binding.utils.BindingUtils; 
  6.   import com.ny.flex.centralManagement.manager.GlobalObjectManager; 
  7.   [Bindable] 
  8.   public  var gom:GlobalObjectManager=GlobalObjectManager.getInstance(); 
  9.  ]]>  
  10. </mx:Script>  
  11.     <mx:HBox  horizontalAlign=”center” verticalAlign=”top”  width=”100%” height=”100%” y=”0″ x=”0″>  
  12.     <mx:ViewStack id=”viewStack”  resizeToContent=”true” selectedIndex=”{gom.viewStackSelectedIndex}” >  
  13.         <views:LoginView  />  
  14.         <views:BuddyListView/>  
  15.     </mx:ViewStack>  
  16.     </mx:HBox>  
  17. </mx:Application>  

 再回头看看在

LoginService 代码中的loginHandler方法,在此viewStackSelectedIndex 全局对象被更新。

LoginService

代码中的loginHandler方法,在此viewStackSelectedIndex 全局对象被更新。

 

 

 

Xml代码
  1. private function loginHandler(event:DataManagerResultEvent):void {  
  2.   var userName:String = event.result as String;  
  3.   if(userName){  
  4.    gom.loginUserName = userName;  
  5.    gom.viewStackSelectedIndex=1;  
  6.   }  
  7.  }  

 

 

 

 

[Bindable]元标签使得其值的改变立刻生效。

BuddyList.mxml代码:

Xml代码
  1. <?xml version=”1.0″ encoding=”utf-8″?>  
  2. <mx:Panel xmlns:mx=”http://www.adobe.com/2006/mxml” title=”Buddy List of {gom.loginUserName}” creationComplete=”init()” width=”500″ height=”320″>  
  3. <mx:Script>  
  4.  <![CDATA[ 
  5.   import com.ny.flex.centralManagement.service.BuddyService; 
  6.   import com.ny.flex.centralManagement.manager.GlobalObjectManager; 
  7.   import mx.collections.ArrayCollection; 
  8.   import mx.rpc.events.ResultEvent; 
  9.   [Bindable] 
  10.   public var gom:GlobalObjectManager = GlobalObjectManager.getInstance(); 
  11.    
  12.   private function init():void{ 
  13.    BuddyService.getInstance().getBuddyList(); 
  14.   } 
  15.  ]]>  
  16. </mx:Script>  
  17.   
  18.  <mx:DataGrid id=”buddyList”  dataProvider=”{gom.mybuddyList}”  borderStyle=”none” width=”100%” height=”100%” >  
  19.        <mx:columns>  
  20.         <mx:DataGridColumn dataField=”firstName” headerText=”First Name”/>  
  21.         <mx:DataGridColumn dataField=”lastName” headerText=”Last Name”/>  
  22.     </mx:columns>  
  23.   
  24.  </mx:DataGrid>  
  25. </mx:Panel>  

 

 

 

 

BuddyService是另一个服务类代码用来和远程对象通讯。

这是最符合本人喜好的Flex程序的框架结构。它的优点是非常的清晰,没有累赘的发送和监听事件的工作,并且代码非常容易维护。遗憾的是,在此还没有获得足够的理论支持这一框架理论。

再来看看MVC框架的代表:MVC-Cairngorm

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值