最近在学习flex,感觉不错就给转过来了。

最近学习flex,参考了不少网上的资料,特别是 中国flex开发者(http://www.flexer.cn/)。flex数据交互是一个关键,做个学习总结,请flex老鸟指正!


flex和后端的数据交互有很多方式,flex可以使用ActionScript读写文件(xml、txt)的形式存储显示数据,

在Flex 3.0中新增了对本地数据库(.db格式)操作的类,可用于读取本地的数据库数据。新增了对PDF数据

操作的类,可用于读取PDF数据。


xml文件方式


XML优点是简单小巧、存储方便、检索快速。所以,XML常用于数据存储和数据交换。Flex 3.使用URLLoader类可方便地传输XML数据。

使用XML方式传输数据的步骤如下所示。

新建名为"tree.xml"文件,用以存储XML数据:

Xml代码 ​


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <menus>
  3. <node label="Mail">
  4. <node label="Inbox"/>
  5. <node label="Personal Folder">
  6. <node label="Demo"/>
  7. <node label="Personal"/>
  8. <node label="Saved Mail"/>
  9. <node label="bar"/>
  10. </node>
  11. <node label="Calendar"/>
  12. <node label="Sent"/>
  13. <node label="Trash"/>
  14. </node>
  15. </menus>


<?xml version="1.0" encoding="utf-8"?> <menus>     <node label="Mail">         <node label="Inbox"/>         <node label="Personal Folder">             <node label="Demo"/>             <node label="Personal"/>             <node label="Saved Mail"/>             <node label="bar"/>         </node>         <node label="Calendar"/>         <node label="Sent"/>         <node label="Trash"/>     </node> </menus>


xml文件的读写我们可以用FileStream类来实现:

读取xml文件:

Javascript代码 ​


  1. var testXML:XML;
  2. var file:File = File.documentsDirectory.resolvePath("tree.xml");
  3. var fileStream:FileStream = new FileStream();
  4. fileStream.open(file, FileMode.READ);
  5. testXML = XML(fileStream.readUTFBytes(fileStream.bytesAvailable));
  6. fileStream.close();


var testXML:XML;
var file:File = File.documentsDirectory.resolvePath("tree.xml");
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);
testXML = XML(fileStream.readUTFBytes(fileStream.bytesAvailable));
fileStream.close();


写回xml文件

Javascript代码 ​


  1. var testXML:XML=<content>content</content>......;
  2. var file:File = File.documentsDirectory.resolvePath("tree.xml");
  3. var fileStream:FileStream = new FileStream();
  4. fileStream.open(file, FileMode.WRITE);
  5. var outputString:String = '<?xml version="1.0" encoding="utf-8"?>/n';
  6. outputString += testXML.toXMLString();
  7. fileStream.writeUTFBytes(outputString);
  8. fileStream.close();


var testXML:XML=<content>content</content>......;
var file:File = File.documentsDirectory.resolvePath("tree.xml");
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
var outputString:String = '<?xml version="1.0" encoding="utf-8"?>/n';
outputString += testXML.toXMLString();
fileStream.writeUTFBytes(outputString);
fileStream.close();


需要说明一下的是文件打开方式:FileMode

READ --设置文件打开方式为只读

WRITE--设置文件打开方式为写数据。文件不存在,则创建;文件存在,则覆盖原有数据。

APPEND--设置文件打开方式为追加。文件不存在,则创建;文件存在,则新数据从文件末尾开始增加。

UPDATE--设置文件打开方式为读写。文件不存在,则创建。设置该模式通常用于随机读写访问文件。可以从文件的任意位置读取,写入数据时,只有写入位置的存在字节被覆盖,其他所有字节不受影响。


这里我们使用URLRequest类来加载xml数据,编写应用程序初始化处理函数loadXML。

变量,用以指明XML文件路径。

public function loadXML():void//应用程序初始化处理函数

{

//定义URLRequest实例,指定文件地址。

var request:URLRequest=new URLRequest("tree.xml");

loader.load(request);//加载XML文件

loader.addEventListener(Event.COMPLETE,completeHandle); //添加加载完成时的监听

}


loader.addEventListener(Event.COMPLETE,completeHandle)语句表示添加对XML加载完成事件的监听。一旦加载完成执行

completeHandle函数。完成剩余MXML代码。剩余代码包括completeHandle函数,<mx:Tree>组件设计等。

以下代码是完整的MXML代码。

Java代码 ​


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" fontFamily="simsun"
  3. fontSize="12" layout="absolute" width="242" height="442" creationComplete="loadXML()">
  4. <mx:Script>
  5. <![CDATA[
  6. import mx.collections.ArrayCollection;
  7. import mx.rpc.events.ResultEvent;
  8. public var loader:URLLoader=new URLLoader();
  9. public var menus:XML=new XML();
  10. public function loadXML():void
  11. {
  12. var request:URLRequest=new URLRequest("tree.xml");
  13. loader.load(request);
  14. loader.addEventListener(Event.COMPLETE,completeHandle);
  15. }
  16. public function completeHandle(e:Event):void
  17. {
  18. menus=XML(loader.data);
  19. var results:XMLList=menus.node;
  20. tree.dataProvider=results;
  21. }
  22. ]]>
  23. </mx:Script>

  24. <mx:Tree id="tree" x="10" y="35" width="218" height="397" labelField="@label" />
  25. <mx:Label x="10" y="10" text="Tree Nodes From XML File"/>
  26. </mx:Application>


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" fontFamily="simsun"
fontSize="12" layout="absolute" width="242" height="442" creationComplete="loadXML()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
public var loader:URLLoader=new URLLoader();
public var menus:XML=new XML();
public function loadXML():void
{
var request:URLRequest=new URLRequest("tree.xml");
loader.load(request);
loader.addEventListener(Event.COMPLETE,completeHandle);
}
public function completeHandle(e:Event):void
{
menus=XML(loader.data);
var results:XMLList=menus.node;
tree.dataProvider=results;
}
]]>
</mx:Script>

<mx:Tree id="tree" x="10" y="35" width="218" height="397" labelField="@label" />
<mx:Label x="10" y="10" text="Tree Nodes From XML File"/>
</mx:Application>




<mx:HTTPService>组件方式



<mx:HTTPService>组件可与所有的后端程序交互。例如,ASP、ASP.Net、JSP、PHP等。

以下是一个<mx:HTTPService>组件语法示例:

<mx:HTTPService id="feedRequest" url="http://localhost:8080/myflex/helloworld?para_1=para_1&para_2=para_2" result="showResult(event)" />

id唯一标识该组件,url是数据提交的地址,可以在地址后面添加参数,提交到后端进行处理,处理后

再返回Flex可识别的数据类型,如数组型、XML型、Object型等。


<mx:HTTPService>组件返回的数据存储于ResultEvent类中。使用<mx:HTTPService>组件的result事件可处理HTTP程序返回的数据。

eg. <mx:HTTPService result="处理函数名">


返回的数据存储于ResultEvent类的result属性下。各种数据的具体位置与HTTP程序的处理结果有关。

数据返回后的处理方法示例:

Java代码 ​


  1. import mx.rpc.events.ResultEvent;
  2. import mx.controls.Alert;

  3. private function showResult(e:ResultEvent):void
  4. {
  5. Alert.show(e.result as String);
  6. }


import mx.rpc.events.ResultEvent;                       
import mx.controls.Alert;

private function showResult(e:ResultEvent):void
{
Alert.show(e.result as String);
}



来一个简单的例子会让你更加明白的!


这是客户端mxml的源代码:

Xml代码 ​


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" >
  3. <mx:Script>
  4. <![CDATA[
  5. import mx.rpc.events.ResultEvent;
  6. import mx.controls.Alert;

  7. private var arr:Array=new Array();
  8. private function addHandle():void
  9. {
  10. myHttp.url="http://localhost:8080/myflex/sum";
  11. if(arr.length>0)
  12. myHttp.url+="?";
  13. for(var i:int=0;i<arr.length;i++)
  14. {
  15. if(i!=arr.length-1)
  16. myHttp.url+="num="+arr[i].para.toString()+"&";
  17. else
  18. myHttp.url+="num="+arr[i].para.toString();
  19. }
  20. Alert.show(myHttp.url);
  21. myHttp.send();
  22. }

  23. private function addData():void
  24. {
  25. var obj:Object=new Object();
  26. obj.para=txtPara.text;
  27. arr.push(obj);
  28. dg.dataProvider=arr;
  29. txtPara.text="";
  30. dg.validateNow();
  31. }

  32. private function delData():void
  33. {
  34. arr=new Array();
  35. dg.dataProvider=arr;
  36. dg.validateNow();
  37. }

  38. private function httpHandle(e:ResultEvent):void
  39. {
  40. lblResult.text=e.result.sumTag;
  41. }
  42. ]]>
  43. </mx:Script>
  44. <mx:HTTPService id="myHttp" showBusyCursor="true" result="httpHandle(event);" useProxy="false"/>
  45. <mx:Panel title="测试HTTPService" width="368" height="334" x="78" y="30" layout="absolute">
  46. <mx:Label text="叠加参数:" x="110" y="26"/>
  47. <mx:TextInput id="txtPara" x="161" y="24" width="95"/>
  48. <mx:DataGrid id="dg" x="76" y="64" height="166" width="179">
  49. <mx:columns>
  50. <mx:DataGridColumn dataField="para" headerText="参数列表"/>
  51. </mx:columns>
  52. </mx:DataGrid>
  53. <mx:Button label="添加" click="addData();" x="277" y="26"/>
  54. <mx:Button label="删除" click="delData();" x="277" y="64"/>
  55. <mx:Label text="叠加结果是:" x="58" y="253"/>
  56. <mx:Label x="126" y="253" id="lblResult"/>
  57. <mx:Button label="计算" click="addHandle();" x="277" y="249"/>
  58. </mx:Panel>
  59. </mx:Application>


<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" >  <mx:Script>         <![CDATA[           import mx.rpc.events.ResultEvent;                 import mx.controls.Alert;                         private var arr:Array=new Array();                private function addHandle():void              {       myHttp.url="http://localhost:8080/myflex/sum";                                                            if(arr.length>0)                                      myHttp.url+="?";       for(var i:int=0;i<arr.length;i++)                  {           if(i!=arr.length-1)               myHttp.url+="num="+arr[i].para.toString()+"&";           else               myHttp.url+="num="+arr[i].para.toString();       }       Alert.show(myHttp.url);       myHttp.send();                          }      private function addData():void            {       var obj:Object=new Object();                  obj.para=txtPara.text;                       arr.push(obj);                               dg.dataProvider=arr;                          txtPara.text="";                            dg.validateNow();                         }      private function delData():void            {       arr=new Array();                                    dg.dataProvider=arr;                        dg.validateNow();                         }      private function httpHandle(e:ResultEvent):void   {    lblResult.text=e.result.sumTag;   }         ]]>      </mx:Script>    <mx:HTTPService id="myHttp" showBusyCursor="true" result="httpHandle(event);" useProxy="false"/>  <mx:Panel title="测试HTTPService" width="368" height="334" x="78" y="30" layout="absolute">      <mx:Label text="叠加参数:" x="110" y="26"/>      <mx:TextInput id="txtPara" x="161" y="24" width="95"/>       <mx:DataGrid id="dg" x="76" y="64" height="166" width="179">          <mx:columns>              <mx:DataGridColumn dataField="para" headerText="参数列表"/>          </mx:columns>      </mx:DataGrid>      <mx:Button label="添加" click="addData();" x="277" y="26"/>        <mx:Button label="删除" click="delData();" x="277" y="64"/>        <mx:Label text="叠加结果是:" x="58" y="253"/>      <mx:Label x="126" y="253" id="lblResult"/>        <mx:Button label="计算" click="addHandle();" x="277" y="249"/>     </mx:Panel> </mx:Application>


"http://localhost:8080/myflex/sum"是一个servlet的映射地址,actionscript方法addHandle将每一个数字参数添加到url映射地

址后面并且向服务器发送请求,addData方法把输入的数字显示到下方列表,delData方法删除整个列表,httpHandle方法处理服务器

的返回值。其中e.result.sumTag表示取得xml返回数据中sumTag标签中的内容。

以下是servlet中对接收参数的处理:

Java代码 ​


  1. public void doPost(HttpServletRequest request, HttpServletResponse response)
  2. throws ServletException, IOException
  3. {
  4. String[] para = request.getParameterValues("num");
  5. int sum = 0;
  6. if (para != null)
  7. {
  8. for (int i = 0; i < para.length; i++)
  9. {
  10. if (para[i] != null && !"".equals(para[i]))
  11. {
  12. sum = sum + Integer.parseInt(para[i]);
  13. }
  14. }
  15. }
  16. response.getWriter().print(
  17. "<?xml version=/"1.0/" encoding=/"utf-8/"?><sumTag>" + sum
  18. + "</sumTag>");
  19. }


public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String[] para = request.getParameterValues("num");
int sum = 0;
if (para != null)
{
for (int i = 0; i < para.length; i++)
{
if (para[i] != null && !"".equals(para[i]))
{
sum = sum + Integer.parseInt(para[i]);
}
}
}
response.getWriter().print(
"<?xml version=/"1.0/" encoding=/"utf-8/"?><sumTag>" + sum
+ "</sumTag>");
}



下面是例子运行的截图:


用actionscript给服务器请求添加参数难免会很麻烦,使用mx:request标签就可以解决这一问题,可以把他

嵌套到HTTPService标签中实现参数的提交。如下例所示:

Xml代码 ​


  1. <mx:request>
  2. <txtPara>{txtPara.text}</txtPara>
  3. </mx:request>


<mx:request>       <txtPara>{txtPara.text}</txtPara>  </mx:request>


其中txtPara是发送到服务器端参数的名城,标签体是参数值,而标签体的值就是下方文本框的值。

以下是完整的mxml文件:

Xml代码 ​


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" >
  3. <mx:Script>
  4. <![CDATA[
  5. import mx.rpc.events.ResultEvent;
  6. import mx.controls.Alert;
  7. private function httpHandle(e:ResultEvent):void
  8. {
  9. Alert.show(e.result.Result);
  10. }
  11. ]]>
  12. </mx:Script>
  13. <mx:HTTPService id="myHttp" url="http://localhost:8080/myflex/http" showBusyCursor="true" result="httpHandle(event);" useProxy="false">
  14. <mx:request>
  15. <txtPara>{txtPara.text}</txtPara>
  16. </mx:request>
  17. </mx:HTTPService>
  18. <mx:Panel title="TEST HTTPService" width="368" height="140" x="78" y="30" layout="absolute">
  19. <mx:Label text="PARA" x="110" y="26"/>
  20. <mx:TextInput id="txtPara" x="161" y="24" width="95"/>
  21. <mx:Label text="The para sent to service is:" x="58" y="53"/>
  22. <mx:Label x="126" y="53" id="lblResult"/>
  23. <mx:Button label="Submit" click="myHttp.send()" x="277" y="53"/>
  24. </mx:Panel>
  25. </mx:Application>


<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" >  <mx:Script>         <![CDATA[           import mx.rpc.events.ResultEvent;                 import mx.controls.Alert;                         private function httpHandle(e:ResultEvent):void    {    Alert.show(e.result.Result);   }         ]]>      </mx:Script>    <mx:HTTPService id="myHttp" url="http://localhost:8080/myflex/http" showBusyCursor="true" result="httpHandle(event);" useProxy="false">   <mx:request>           <txtPara>{txtPara.text}</txtPara>      </mx:request>  </mx:HTTPService>  <mx:Panel title="TEST HTTPService" width="368" height="140" x="78" y="30" layout="absolute">      <mx:Label text="PARA" x="110" y="26"/>        <mx:TextInput id="txtPara" x="161" y="24" width="95"/>       <mx:Label text="The para sent to service is:" x="58" y="53"/>      <mx:Label x="126" y="53" id="lblResult"/>        <mx:Button label="Submit" click="myHttp.send()" x="277" y="53"/>     </mx:Panel> </mx:Application>


在服务器端就可以从request中取到txtPara参数的值,这里没有做过多处理,只是在后端取到这个值又通过xml形式返还到客户端。



mx:request组件一般是结合mx:form组件一起使用,flex提供了完备的数据校验功能,如对字符串的校验mx:StringValidator、

对电话号码验证的mx:PhoneNumberValidator、对日期验证的mx:DateValidator、对电子邮件验证的mx:EmailValidator、对邮编验证

的mx:ZipCodeValidator等等。下面这个示例来自Flex的在线文档,主要展示flex的form验证功能,没有数据的提交。


Xml代码 ​


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- Simple example to demonstrate Form layout container. -->
  3. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
  4. <mx:Panel title="Form Container Example" height="75%" width="75%"
  5. paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10">
  6. <mx:Text width="100%" color="blue"
  7. text="Moving from one form field to another triggers the validator."/>
  8. <mx:Form width="100%" height="100%">
  9. <mx:FormHeading label="Enter values into the form."/>
  10. <mx:FormItem label="First name">
  11. <mx:TextInput id="fname" width="200"/>
  12. </mx:FormItem>
  13. <mx:FormItem label="Date of birth (mm/dd/yyyy)">
  14. <mx:TextInput id="dob" width="200"/>
  15. </mx:FormItem>
  16. <mx:FormItem label="E-mail address">
  17. <mx:TextInput id="email" width="200"/>
  18. </mx:FormItem>
  19. <mx:FormItem label="Age">
  20. <mx:TextInput id="age" width="200"/>
  21. </mx:FormItem>
  22. <mx:FormItem label="SSN">
  23. <mx:TextInput id="ssn" width="200"/>
  24. </mx:FormItem>
  25. <mx:FormItem label="Zip">
  26. <mx:TextInput id="zip" width="200"/>
  27. </mx:FormItem>
  28. <mx:FormItem label="Phone">
  29. <mx:TextInput id="phone" width="200"/>
  30. </mx:FormItem>
  31. </mx:Form>
  32. </mx:Panel>

  33. <mx:StringValidator source="{fname}" property="text" minLength="4" maxLength="12"/>
  34. <mx:PhoneNumberValidator source="{phone}" property="text"/>
  35. <mx:DateValidator source="{dob}" property="text"/>
  36. <mx:EmailValidator source="{email}" property="text"/>
  37. <mx:NumberValidator source="{age}" property="text" integerError="Enter Integer value"
  38. minValue="18" maxValue="100" domain="int"/>
  39. <mx:SocialSecurityValidator source="{ssn}" property="text"/>
  40. <mx:ZipCodeValidator source="{zip}" property="text"/>
  41. </mx:Application>


<?xml version="1.0" encoding="utf-8"?> <!-- Simple example to demonstrate Form layout container. --> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">     <mx:Panel title="Form Container Example" height="75%" width="75%"          paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10">         <mx:Text width="100%" color="blue"             text="Moving from one form field to another triggers the validator."/>         <mx:Form width="100%" height="100%">             <mx:FormHeading label="Enter values into the form."/>             <mx:FormItem label="First name">                 <mx:TextInput id="fname" width="200"/>             </mx:FormItem>             <mx:FormItem label="Date of birth (mm/dd/yyyy)">                 <mx:TextInput id="dob" width="200"/>             </mx:FormItem>             <mx:FormItem label="E-mail address">                 <mx:TextInput id="email" width="200"/>             </mx:FormItem>             <mx:FormItem label="Age">                 <mx:TextInput id="age" width="200"/>             </mx:FormItem>             <mx:FormItem label="SSN">                 <mx:TextInput id="ssn" width="200"/>             </mx:FormItem>             <mx:FormItem label="Zip">                 <mx:TextInput id="zip" width="200"/>             </mx:FormItem>             <mx:FormItem label="Phone">                 <mx:TextInput id="phone" width="200"/>             </mx:FormItem>         </mx:Form>     </mx:Panel>      <mx:StringValidator source="{fname}" property="text" minLength="4" maxLength="12"/>     <mx:PhoneNumberValidator source="{phone}" property="text"/>     <mx:DateValidator source="{dob}" property="text"/>     <mx:EmailValidator source="{email}" property="text"/>     <mx:NumberValidator source="{age}" property="text" integerError="Enter Integer value"         minValue="18" maxValue="100" domain="int"/>     <mx:SocialSecurityValidator source="{ssn}" property="text"/>     <mx:ZipCodeValidator source="{zip}" property="text"/> </mx:Application>