听棠.NET

用积极乐观的心态,面对压力
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

问题:今天我在Flex的module中使用RemoteObject的方式与服务端进行AMF的远程数据调用。第一次切换到module时是没有问题的,但第二次切换到module时,发现总是报错,无法完成远程调用。为此困惑极了。

我在remoting访问时,使用了一个自定义的参数类:

package VO
{
 [RemoteClass(alias="ServiceLibrary.SystemFramework.UserInfoSearchCondition")]
 public class UserInfoSearchConditionVO
 {
  public function UserInfoSearchConditionVO()
  {
  }
  public var UserName:String;
  public var DepartmentId:String;
 }
}

这个定义里使用到了:[RemoteClass(alias="ServiceLibrary.SystemFramework.UserInfoSearchCondition")]

这就是本地对象与“远程服务端类”的别名定义,这个大家都应该知道的。

 

远程调用时:

var condition:UserInfoSearchConditionVO=new UserInfoSearchConditionVO();
condition.UserName=txtSearchUserName.text;
var resp1:Responder=new Responder(onUserSearchCountSuccess,onUserSearchCountFaild);
nc.call("ServiceLibrary.SystemFramework.UserInfoFacade.GetUserInfoCountByCondition",resp1,condition);

 

但不知道为什么,在第一次Module时加载是可以的。在第二次加载module时,此“注册”信息会丢失。

 

解决方法:需要明确声明此注册信息,代码如下:

import flash.net.registerClassAlias;       
import mx.messaging.messages.RemotingMessage;   
import VO.UserInfoSearchConditionVO;
registerClassAlias("ServiceLibrary.SystemFramework.UserInfoSearchCondition", UserInfoSearchConditionVO);

以上的代码可以放在自己的module里,或者也可以直接放在Application上,声明一次也就可以了,子Module不需要更申明了。

最后的代码我帖出来,如果你能看懂就最好了,看不懂我也没办法了:)

 

<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:fx="http://ns.adobe.com/mxml/2009"
     xmlns:s="library://ns.adobe.com/flex/spark"
     xmlns:mx="library://ns.adobe.com/flex/halo" layout="vertical" width="100%" height="100%"   
     creationComplete="module1_creationCompleteHandler(event)" >
<fx:Script>
 <![CDATA[
  import mx.events.ListEvent;
  import AppConfig.Connection;

  
  import mx.events.FlexEvent; 
  import mx.controls.Alert;
  public var nc:NetConnection;  
     import mx.collections.ArrayCollection; 
  public var pageCount:int=10;
  public var curPage:int=0;
  public var totalCount:int=0;
  
  //这里就是需要申明注册别名的地方。
  import flash.net.registerClassAlias;      
  import mx.messaging.messages.RemotingMessage;  
  import VO.UserInfoSearchConditionVO;
  registerClassAlias("ServiceLibrary.SystemFramework.UserInfoSearchCondition", UserInfoSearchConditionVO);
  
  protected function module1_creationCompleteHandler(event:FlexEvent):void
  {
   // TODO Auto-generated method stub
   nc=new NetConnection();
   nc.objectEncoding=ObjectEncoding.AMF3;
   var gatewayUrl:String =AppConfig.Connection.getInstance().connectionString;
   
   nc.addEventListener(NetStatusEvent.NET_STATUS,netStateHandle);
   nc.connect(gatewayUrl);
  }
  
  protected function netStateHandle(evt:NetStatusEvent):void
  {
   Alert.show("连接出错了!","出错了");
  }


  protected function btnSearch_clickHandler(event:MouseEvent):void
  {
   // TODO Auto-generated method stub
   
   
   
   BindGrid();
   
   
  }
  
  protected function BindGrid():void
  {
   
   
   
   var condition:UserInfoSearchConditionVO=new UserInfoSearchConditionVO();
   condition.UserName=txtSearchUserName.text;
   
   var resp1:Responder=new Responder(onUserSearchCountSuccess,onUserSearchCountFaild);
   nc.call("ServiceLibrary.SystemFramework.UserInfoFacade.GetUserInfoCountByCondition",resp1,condition);
   
   
   var resp2:Responder=new Responder(onUserSearchSuccess,onUserSearchFaild);
   nc.call("ServiceLibrary.SystemFramework.UserInfoFacade.GetUserInfoByCondition",resp2,condition,curPage,pageCount);
  }
  
  protected function onUserSearchCountSuccess(re:Object):void{
   this.totalCount= re as int;
   if(curPage>0)
    this.btnPrev.visible=true;
   else
    this.btnPrev.visible=false;
   
   if((curPage+1) * pageCount >=totalCount)
    this.btnNext.visible=false;
   else
    this.btnNext.visible=true;
  }
  protected function onUserSearchCountFaild(re:String):void{
   Alert.show("获取数据出错!","出错了");
  }
  
  protected function onUserSearchSuccess(re:ArrayCollection):void{
   gridUser.dataProvider =re;
  }
  protected function onUserSearchFaild(re:String):void{
   Alert.show("获取数据出错!","出错了");
  }
  
  protected function btnNext_clickHandler(event:MouseEvent):void
  {
   // TODO Auto-generated method stub
   curPage++;
   BindGrid();
  }
  
  
  protected function btnPrev_clickHandler(event:MouseEvent):void
  {
   // TODO Auto-generated method stub
   curPage--;
   BindGrid();
   
  }
  


  


  protected function gridUser_itemClickHandler(event:ListEvent):void
  {
   // TODO Auto-generated method stub
   this.currentState="edit";
  }


  

 ]]>
</fx:Script>
 <mx:states>
  <s:State name="view"/>
  <s:State name="edit"/>
 </mx:states>
 <s:HGroup width="100%" height="100%">
  
  <s:Panel width="250" height="100%" title="用户管理">
   <s:layout>
    <s:VerticalLayout/>
   </s:layout>
   <s:HGroup width="100%" height="29">
    <s:TextInput id="txtSearchUserName" height="29" width="162"/>
    <mx:Button id="btnSearch" label="查询mailto:"%20icon="@Embed(source='assets/images/search.png')" height="29" labelPlacement="right" click="btnSearch_clickHandler(event)">
     
    </mx:Button>
   </s:HGroup>
   <mx:HRule width="100%"/>
   <mx:ButtonBar height="20" height.view="32">
    <mx:dataProvider>
     <fx:Object label="新增mailto:"%20icon="@Embed(source='assets/images/Add.png')" />
     <fx:Object label="删除mailto:"%20icon="@Embed(source='assets/images/Remove.png')" />
    </mx:dataProvider>
   </mx:ButtonBar>
   <mx:DataGrid id="gridUser" width="100%" height="100%" itemClick="gridUser_itemClickHandler(event)">
    <mx:columns>
     <mx:DataGridColumn headerText="用户名" dataField="UserName"/>
     
    </mx:columns>
   </mx:DataGrid>
   <s:HGroup x="393" y="264" width="100%" height="26">
    <mx:LinkButton label="上一页" id="btnPrev" visible="false" click="btnPrev_clickHandler(event)"/>
    <mx:LinkButton label="下一页" id="btnNext" visible="false" click="btnNext_clickHandler(event)"/>
   </s:HGroup>
  </s:Panel>
  <mx:VRule height="100%" baseColor="#A75757"/>
  <s:Panel id="pnlUserEdit" horizontalCenter="0" verticalCenter="0" width="100%" height="100%" dropShadowVisible="true"  title="用户信息"
      includeIn="edit">
   <s:layout>
    <s:VerticalLayout/>
   </s:layout>
   
   <mx:Form width="100%" height="100%">
    <mx:FormItem label="帐号:" required="true" >
     <s:TextInput  id="account" >
      
     </s:TextInput>
    </mx:FormItem>
    <mx:FormItem label="密码:" required="true">
     <s:TextInput id="pwd" displayAsPassword="true">
      
     </s:TextInput>
     
    </mx:FormItem>
    <mx:FormItem>
     <s:CheckBox id="chkRememberMe" selected="true" label="下次记住我">
      
     </s:CheckBox>
    </mx:FormItem>
    <mx:FormItem horizontalAlign="right">
     <s:Button label="登录" id="btnSave"  >
      
     </s:Button>
    </mx:FormItem>
    
   </mx:Form>
   
  </s:Panel>
 </s:HGroup>
</mx:Module>

 

 

最后,我再主张一下我的设计的原则:

在客户端与服务端进行远程数据调用时,我不太主张采用“简单参数”模式,比如查询用户功能吧,我可以使用username,deparmentId...等等参数来进行参数调用,但这样有个扩展性问题:那就是当以后要添加“查询条件”时,不得不修改接口。这就是会导致客户端要修改N个调用地方,服务端也要进行接口修改,这就会带来很大的扩展问题。

因此,我建议可以自定义一个“Condition查询类”与“服务端”的相对应,这样接口的参数就只需要一个,而且类型不变。

以后如果要扩展“查询条件”时,只需要在“客户端”添加一个属性,并赋值就OK了。在“服务端”则也只要添加属性,并修改实现代码就OK了,不再需要修改两端的“接口”了。。