使用Flex+Cairngorm+AIR制作列车时刻表查询工具[连载二]

索引

  1. 使用Flex+Cairngorm+AIR制作列车时刻表查询工具[连载一]
  2. 使用Flex+Cairngorm+AIR制作列车时刻表查询工具[连载二]
  3. 使用Flex+Cairngorm+AIR制作列车时刻表查询工具[连载三]

打开Flex Builder创建一个新项目,命名为“TrainSchedule”。在项目的libs目录中,放入我们要引入的Cairngorm的类库(Cairngorm.swc)。

在src目录中建立一个名为data的文件夹,放入我们要查询的SQLite数据库文件(TrainsInfo.db),这个文件也可以在源码的相应目录找到。

按照MVC的原则,建立如下的几个目录(为了让大家了解这些目录的用途,我特意做了备注):

  1. control – 用于定义前端控制器
  2. business – 包含Service和代理(delegate)
  3. view – 视图和组件
  4. command – 命令,代码的主要执行部分
  5. event – 自定义事件
  6. model – 数据模型
  7. vo - ValueObject

首先,让我们来完成视图部分的制作,通过分析,我们发现需要3个视图:

  1. 视图1:搜索界面
  2. 视图2:搜索结果(按照列车车次检索)界面
  3. 视图3:搜索结果(按照出发和目的地检索)界面

建立这3个视图文件:

SearchForm.mxml

 

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" horizontalAlign="left" verticalAlign="middle">
  3. <mx:Script>
  4. <![CDATA[
  5. import com.example.event.SearchByTrainNameEvent;
  6. import com.example.event.SearchByStationEvent;
  7. import com.example.model.TrainModelLocator;
  8. private var model : TrainModelLocator = TrainModelLocator.getInstance();
  9. private function searchByTrainName():void {
  10. var event:SearchByTrainNameEvent = new SearchByTrainNameEvent();
  11. event.trainName = trainNameInput.text;
  12. event.dispatch();
  13. }
  14. private function searchByStation():void {
  15. var event:SearchByStationEvent = new SearchByStationEvent();
  16. event.start = startStation.text;
  17. event.end = endStation.text;
  18. event.dispatch();
  19. }
  20. ]]>
  21. </mx:Script>
  22. <mx:VBox>
  23. <mx:Image source="assets/png-0005.png"/>
  24. </mx:VBox>
  25. <mx:VRule height="240" alpha="0.15"/>
  26.  
  27. <mx:VBox>
  28.  
  29. <mx:Form>
  30. <mx:Label text="按照列车车次查询:" />
  31. <mx:TextInput id="trainNameInput" width="197" text="T585"/>
  32. <mx:Button label="查询" click="searchByTrainName()"/>
  33. <mx:Label text="按出发地点-目的地查询:" />
  34. <mx:HBox>
  35. <mx:TextInput width="81" id="startStation" text="北京"/>
  36. <mx:Label text="-" />
  37. <mx:TextInput width="81" id="endStation" text="邯郸"/>
  38. </mx:HBox>
  39. <mx:Button label="查询" click="searchByStation()"/>
  40. <mx:Label text="查询来源" />
  41. <mx:HBox>
  42. <mx:RadioButton label="WebService" selected="true" click="model.currentService = 'webService'"/>
  43. <mx:RadioButton label="本地数据库" click="model.currentService = 'dataBase'"/>
  44. </mx:HBox>
  45. </mx:Form>
  46. </mx:VBox>
  47. </mx:HBox>

 

SearchResultByStationList.mxml

 

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Box xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" creationComplete="init()">
  3. <mx:Script>
  4. <![CDATA[
  5. import com.example.model.TrainModelLocator;
  6. import com.example.event.SearchByTrainNameEvent;
  7. [Bindable]
  8. private var model : TrainModelLocator = TrainModelLocator.getInstance();
  9. private function init():void {
  10. //
  11. }
  12. private function doSearch():void {
  13. var event:SearchByTrainNameEvent = new SearchByTrainNameEvent();
  14. event.trainName = dg.selectedItem.TrainCode;
  15. event.dispatch();
  16. }
  17. ]]>
  18. </mx:Script>
  19. <mx:HBox width="100%" height="30">
  20. <mx:Label text="{'搜索车站('+model.startStation+'到'+model.arriveStation+')的返回结果:'+model.currentStaionList.trainStationList.length}"/>
  21. <mx:Spacer width="100%"/>
  22. <mx:Button label="&lt;--返回" click="model.currentState = ''"/>
  23. </mx:HBox>
  24. <mx:DataGrid id="dg" width="100%" height="100%" dataProvider="{model.currentStaionList.trainStationList}" itemClick="doSearch()">
  25. <mx:columns>
  26. <mx:DataGridColumn headerText="列车" dataField="TrainCode"/>
  27. <mx:DataGridColumn headerText="始发站" dataField="FirstStation"/>
  28. <mx:DataGridColumn headerText="终点站" dataField="LastStation"/>
  29. <mx:DataGridColumn headerText="开始" dataField="StartStation"/>
  30. <mx:DataGridColumn headerText="开始时间" dataField="StartTime"/>
  31. <mx:DataGridColumn headerText="到达" dataField="ArriveStation"/>
  32. <mx:DataGridColumn headerText="到达时间" dataField="ArriveTime"/>
  33. <mx:DataGridColumn headerText="公里数" dataField="KM"/>
  34. <mx:DataGridColumn headerText="耗费时间" dataField="UseDate"/>
  35. </mx:columns>
  36. </mx:DataGrid>
  37.  
  38. </mx:Box>

 

SearchResultByTrainName.mxml

 

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Box xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%">
  3. <mx:Script>
  4. <![CDATA[
  5. import com.example.model.TrainModelLocator;
  6. [Bindable]
  7. private var model : TrainModelLocator = TrainModelLocator.getInstance();
  8. ]]>
  9. </mx:Script>
  10. <mx:HBox width="100%" height="30">
  11. <mx:Label text="{'搜索列车('+model.currentTrain.name+')的返回结果:'+model.currentTrain.journey.length}"/>
  12. <mx:Spacer width="100%"/>
  13. <mx:Button label="&lt;--返回" click="model.currentState = ''"/>
  14. </mx:HBox>
  15. <mx:DataGrid width="100%" height="100%" dataProvider="{model.currentTrain.journey}">
  16. <mx:columns>
  17. <mx:DataGridColumn headerText="序号" dataField="num" width="30"/>
  18. <mx:DataGridColumn headerText="车站" dataField="TrainStation" width="200"/>
  19. <mx:DataGridColumn headerText="到达时间" dataField="ArriveTime"/>
  20. <mx:DataGridColumn headerText="发车时间" dataField="StartTime"/>
  21. <mx:DataGridColumn headerText="里程" dataField="KM"/>
  22. </mx:columns>
  23. </mx:DataGrid>
  24.  
  25. </mx:Box>

 

主界面中我们分别建立3个状态(包括默认的基础状态),用于显示3 个视图。

TrainSchedule.mxml

 

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:WindowedApplication
  3. xmlns:mx="http://www.adobe.com/2006/mxml"
  4. xmlns:control="com.example.control.*"
  5. xmlns:business="com.example.business.*"
  6. xmlns:view="com.example.view.*"
  7. pageTitle="列车时刻表查询"
  8. currentState="{model.currentState}"
  9. verticalAlign="middle" viewSourceURL="srcview/index.html">
  10.  
  11. <mx:Script>
  12. <![CDATA[
  13. import com.example.model.TrainModelLocator;
  14. [Bindable]
  15. private var model : TrainModelLocator = TrainModelLocator.getInstance();
  16. ]]>
  17. </mx:Script>
  18.  
  19. <mx:Style source="style.css" />
  20.  
  21. <business:Services id="services" />
  22. <control:TrainController id="controller" />
  23.  
  24. <mx:states>
  25. <mx:State name="resultByTrainName">
  26. <mx:RemoveChild target="{searchForm}"/>
  27. <mx:AddChild position="lastChild">
  28. <view:SearchResultByTrainName />
  29. </mx:AddChild>
  30. </mx:State>
  31. <mx:State name="resultByStationList">
  32. <mx:RemoveChild target="{searchForm}"/>
  33. <mx:AddChild position="lastChild">
  34. <view:SearchResultByStationList />
  35. </mx:AddChild>
  36. </mx:State>
  37. </mx:states>
  38.  
  39. <view:SearchForm id="searchForm"/>
  40.  
  41. </mx:WindowedApplication>

 

建立服务调用类:

Services.mxml

 

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <business:ServiceLocator
  3. xmlns:mx="http://www.adobe.com/2006/mxml"
  4. xmlns:business="com.adobe.cairngorm.business.*">
  5.  
  6. <mx:Script>
  7. <![CDATA[
  8. import com.example.model.TrainModelLocator;
  9. ]]>
  10. </mx:Script>
  11.  
  12. <mx:WebService id="trainService" wsdl="{TrainModelLocator.getInstance().wsWSDL}" showBusyCursor="true" useProxy="false">
  13.  
  14. <mx:operation name="getDetailInfoByTrainCode" resultFormat="xml">
  15. <mx:request>
  16. <TrainCode>{TrainModelLocator.getInstance().currentTrain.name}</TrainCode>
  17. <UserID>{""}</UserID>
  18. </mx:request>
  19. </mx:operation>
  20.  
  21. <mx:operation name="getStationAndTimeByStationName" resultFormat="xml">
  22. <mx:request>
  23. <StartStation>{TrainModelLocator.getInstance().startStation}</StartStation>
  24. <ArriveStation>{TrainModelLocator.getInstance().arriveStation}</ArriveStation>
  25. <UserID>{""}</UserID>
  26. </mx:request>
  27. </mx:operation>
  28.  
  29. </mx:WebService>
  30.  
  31. </business:ServiceLocator>

 

代理

然后建立两个代理,分别用于调用WebService服务和本地数据库查询服务:

TrainDelegateWS.as

 

  1. package com.example.business
  2. {
  3. import com.adobe.cairngorm.business.ServiceLocator;
  4.  
  5. import mx.rpc.IResponder;
  6.  
  7. public class TrainDelegateWS {
  8. public function TrainDelegateWS(responder : IResponder) {
  9. this.service = ServiceLocator.getInstance().getWebService("trainService");
  10. this.responder = responder;
  11. }
  12.  
  13. public function getTrainDetail() : void {
  14. var call : Object = service.getDetailInfoByTrainCode();
  15. call.addResponder( responder );
  16. }
  17.  
  18. public function getStationDetail() : void {
  19. var call : Object = service.getStationAndTimeByStationName();
  20. call.addResponder( responder );
  21. }
  22.  
  23. private var responder : IResponder;
  24. private var service : Object;
  25.  
  26. }
  27. }

 

 

TrainDelegateDB.as

 

  1. package com.example.business
  2. {
  3. import com.example.model.TrainModelLocator;
  4.  
  5. import flash.data.SQLConnection;
  6. import flash.data.SQLResult;
  7. import flash.data.SQLStatement;
  8. import flash.events.SQLErrorEvent;
  9. import flash.events.SQLEvent;
  10. import flash.filesystem.File;
  11.  
  12. import mx.collections.ArrayCollection;
  13. import mx.controls.Alert;
  14. import mx.rpc.IResponder;
  15. public class TrainDelegateDB {
  16. private var con:SQLConnection;
  17. private var conForStation:SQLConnection;
  18. private var file:File = File.applicationDirectory.resolvePath("data/TrainsInfo.db");
  19. private var selectStmt:SQLStatement;
  20.  
  21. public function TrainDelegateDB(responder : IResponder) {
  22. this.responder = responder;
  23. con = new SQLConnection();
  24. conForStation = new SQLConnection();
  25. con.addEventListener(SQLEvent.OPEN,openHandler);
  26. con.addEventListener(SQLErrorEvent.ERROR,errorHandler);
  27. conForStation.addEventListener(SQLEvent.OPEN,openHandlerByStation);
  28. conForStation.addEventListener(SQLErrorEvent.ERROR,errorHandler);
  29. }
  30.  
  31. public function getTrainDetail() : void {
  32. con.openAsync(file);
  33. }
  34.  
  35. public function getStationDetail() : void {
  36. conForStation.openAsync(file);
  37. }
  38.  
  39. private var responder : IResponder;
  40.  
  41.  
  42. private function openHandler(e:SQLEvent):void {
  43. selectStmt = new SQLStatement();
  44. selectStmt.sqlConnection = con;
  45. selectStmt.addEventListener(SQLEvent.RESULT, selectResult);
  46. var sql:String = "SELECT * FROM TrainStation WHERE TrainName = '"+TrainModelLocator.getInstance().currentTrain.name+"'";
  47. selectStmt.text = sql;
  48. selectStmt.execute();
  49. }
  50. private function openHandlerByStation(e:SQLEvent):void {
  51. selectStmt = new SQLStatement();
  52. selectStmt.sqlConnection = conForStation;
  53. selectStmt.addEventListener(SQLEvent.RESULT, selectResultByStation);
  54. var sql:String = "SELECT * FROM TrainStation WHERE StationName = '"+TrainModelLocator.getInstance().startStation+"' or StationName = '"+TrainModelLocator.getInstance().arriveStation+"'";
  55. selectStmt.text = sql;
  56. selectStmt.execute();
  57. }
  58. private function errorHandler(e:SQLErrorEvent):void {
  59. Alert.show(e.error.message);
  60. Alert.show(e.error.details);
  61. }
  62. private function selectResult(event:SQLEvent):void {
  63. var result:SQLResult = selectStmt.getResult();
  64. if(result.data != null) {
  65. var model : TrainModelLocator = TrainModelLocator.getInstance();
  66. model.currentTrain.journey = new ArrayCollection();
  67. var count:uint = 1;
  68. for each(var item:Object in result.data) {
  69. var nodeItem:Object = new Object();
  70. nodeItem.num = count;
  71. count++;
  72. nodeItem.TrainStation = item.StationName;
  73. nodeItem.ArriveTime = item.ArriveTime;
  74. nodeItem.StartTime = item.LeaveTime;
  75. nodeItem.KM = item.Distance;
  76. model.currentTrain.journey.addItem(nodeItem);
  77. }
  78. model.currentState = "resultByTrainName";
  79. } else {
  80. Alert.show("对不起,没有找到可用数据");
  81. }
  82. con.close();
  83. }
  84. private function selectResultByStation(event:SQLEvent):void {
  85. var result:SQLResult = selectStmt.getResult();
  86. if(result.data != null) {
  87. var model : TrainModelLocator = TrainModelLocator.getInstance();
  88. model.currentStaionList.trainStationList = new ArrayCollection();
  89. var count:uint = 1;
  90. for each(var item:Object in result.data) {
  91. for(var i:uint = 0;i<result.data.length;i++) {
  92. if(item.TrainName == result.data[i].TrainName && item.StationName != result.data[i].StationName) {
  93. var nodeItem:Object = new Object();
  94. nodeItem.TrainCode = item.TrainName;
  95. //计算始发站
  96. nodeItem.StartStation = model.startStation;
  97. nodeItem.StartTime = "点击查看详情";
  98. nodeItem.ArriveStation = model.arriveStation;
  99. nodeItem.ArriveTime = "点击查看详情";
  100. var hasNode:Boolean = false;
  101. f:for(var j:uint = 0; j<model.currentStaionList.trainStationList.length;j++) {
  102. if(model.currentStaionList.trainStationList[j].TrainCode == item.TrainName) {
  103. hasNode = true;
  104. break f;
  105. }
  106. }
  107. if(!hasNode) model.currentStaionList.trainStationList.addItem(nodeItem);
  108. }
  109. }
  110. }
  111. model.currentState = "resultByStationList";
  112. } else {
  113. Alert.show("对不起,没有找到可用数据");
  114. }
  115. con.close();
  116. }
  117. }
  118. }

 

 

(未完待续)

posted on 2010-11-03 21:30  小斌斌  阅读(581)  评论(0)    收藏  举报

导航