使用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. }

 

 

(未完待续)

你可能感兴趣的:(Flex)