索引
- 使用Flex+Cairngorm+AIR制作列车时刻表查询工具[连载一]
- 使用Flex+Cairngorm+AIR制作列车时刻表查询工具[连载二]
- 使用Flex+Cairngorm+AIR制作列车时刻表查询工具[连载三]
打开Flex Builder创建一个新项目,命名为“TrainSchedule”。在项目的libs目录中,放入我们要引入的Cairngorm的类库(Cairngorm.swc)。
在src目录中建立一个名为data的文件夹,放入我们要查询的SQLite数据库文件(TrainsInfo.db),这个文件也可以在源码的相应目录找到。
按照MVC的原则,建立如下的几个目录(为了让大家了解这些目录的用途,我特意做了备注):
- control – 用于定义前端控制器
- business – 包含Service和代理(delegate)
- view – 视图和组件
- command – 命令,代码的主要执行部分
- event – 自定义事件
- model – 数据模型
- vo - ValueObject
首先,让我们来完成视图部分的制作,通过分析,我们发现需要3个视图:
- 视图1:搜索界面
- 视图2:搜索结果(按照列车车次检索)界面
- 视图3:搜索结果(按照出发和目的地检索)界面
建立这3个视图文件:
SearchForm.mxml
-
<?xml version= "1.0" encoding= "utf-8" ?>
-
<mx :HBox xmlns :mx= "http://www.adobe.com/2006/mxml" horizontalAlign= "left" verticalAlign= "middle" >
-
<mx :Script >
-
<! [CDATA [
-
import com.example.event.SearchByTrainNameEvent;
-
import com.example.event.SearchByStationEvent;
-
import com.example.model.TrainModelLocator;
-
private var model : TrainModelLocator = TrainModelLocator.getInstance ( );
-
private function searchByTrainName ( ) : void {
-
var event :SearchByTrainNameEvent = new SearchByTrainNameEvent ( );
-
event.trainName = trainNameInput. text;
-
event.dispatch ( );
-
}
-
private function searchByStation ( ) : void {
-
var event :SearchByStationEvent = new SearchByStationEvent ( );
-
event. start = startStation. text;
-
event.end = endStation. text;
-
event.dispatch ( );
-
}
-
] ] >
-
</mx :Script >
-
<mx :VBox >
-
<mx :Image source= "assets/png-0005.png" />
-
</mx :VBox >
-
<mx :VRule height= "240" alpha= "0.15" />
-
-
<mx :VBox >
-
-
<mx :Form >
-
<mx :Label text= "按照列车车次查询:" />
-
<mx :TextInput id= "trainNameInput" width= "197" text= "T585" />
-
<mx :Button label= "查询" click= "searchByTrainName()" />
-
<mx :Label text= "按出发地点-目的地查询:" />
-
<mx :HBox >
-
<mx :TextInput width= "81" id= "startStation" text= "北京" />
-
<mx :Label text= "-" />
-
<mx :TextInput width= "81" id= "endStation" text= "邯郸" />
-
</mx :HBox >
-
<mx :Button label= "查询" click= "searchByStation()" />
-
<mx :Label text= "查询来源" />
-
<mx :HBox >
-
<mx :RadioButton label= "WebService" selected= "true" click= "model.currentService = 'webService'" />
-
<mx :RadioButton label= "本地数据库" click= "model.currentService = 'dataBase'" />
-
</mx :HBox >
-
</mx :Form >
-
</mx :VBox >
-
</mx :HBox >
SearchResultByStationList.mxml
-
<?xml version= "1.0" encoding= "utf-8" ?>
-
<mx :Box xmlns :mx= "http://www.adobe.com/2006/mxml" width= "100%" height= "100%" creationComplete= "init()" >
-
<mx :Script >
-
<! [CDATA [
-
import com.example.model.TrainModelLocator;
-
import com.example.event.SearchByTrainNameEvent;
-
[Bindable ]
-
private var model : TrainModelLocator = TrainModelLocator.getInstance ( );
-
private function init ( ) : void {
-
//
-
}
-
private function doSearch ( ) : void {
-
var event :SearchByTrainNameEvent = new SearchByTrainNameEvent ( );
-
event.trainName = dg.selectedItem.TrainCode;
-
event.dispatch ( );
-
}
-
] ] >
-
</mx :Script >
-
<mx :HBox width= "100%" height= "30" >
-
<mx :Label text= "{'搜索车站('+model.startStation+'到'+model.arriveStation+')的返回结果:'+model.currentStaionList.trainStationList.length}" />
-
<mx :Spacer width= "100%" />
-
<mx :Button label= "<--返回" click= "model.currentState = ''" />
-
</mx :HBox >
-
<mx :DataGrid id= "dg" width= "100%" height= "100%" dataProvider= "{model.currentStaionList.trainStationList}" itemClick= "doSearch()" >
-
<mx :columns >
-
<mx :DataGridColumn headerText= "列车" dataField= "TrainCode" />
-
<mx :DataGridColumn headerText= "始发站" dataField= "FirstStation" />
-
<mx :DataGridColumn headerText= "终点站" dataField= "LastStation" />
-
<mx :DataGridColumn headerText= "开始" dataField= "StartStation" />
-
<mx :DataGridColumn headerText= "开始时间" dataField= "StartTime" />
-
<mx :DataGridColumn headerText= "到达" dataField= "ArriveStation" />
-
<mx :DataGridColumn headerText= "到达时间" dataField= "ArriveTime" />
-
<mx :DataGridColumn headerText= "公里数" dataField= "KM" />
-
<mx :DataGridColumn headerText= "耗费时间" dataField= "UseDate" />
-
</mx :columns >
-
</mx :DataGrid >
-
-
</mx :Box >
SearchResultByTrainName.mxml
-
<?xml version= "1.0" encoding= "utf-8" ?>
-
<mx :Box xmlns :mx= "http://www.adobe.com/2006/mxml" width= "100%" height= "100%" >
-
<mx :Script >
-
<! [CDATA [
-
import com.example.model.TrainModelLocator;
-
[Bindable ]
-
private var model : TrainModelLocator = TrainModelLocator.getInstance ( );
-
] ] >
-
</mx :Script >
-
<mx :HBox width= "100%" height= "30" >
-
<mx :Label text= "{'搜索列车('+model.currentTrain.name+')的返回结果:'+model.currentTrain.journey.length}" />
-
<mx :Spacer width= "100%" />
-
<mx :Button label= "<--返回" click= "model.currentState = ''" />
-
</mx :HBox >
-
<mx :DataGrid width= "100%" height= "100%" dataProvider= "{model.currentTrain.journey}" >
-
<mx :columns >
-
<mx :DataGridColumn headerText= "序号" dataField= "num" width= "30" />
-
<mx :DataGridColumn headerText= "车站" dataField= "TrainStation" width= "200" />
-
<mx :DataGridColumn headerText= "到达时间" dataField= "ArriveTime" />
-
<mx :DataGridColumn headerText= "发车时间" dataField= "StartTime" />
-
<mx :DataGridColumn headerText= "里程" dataField= "KM" />
-
</mx :columns >
-
</mx :DataGrid >
-
-
</mx :Box >
主界面中我们分别建立3个状态(包括默认的基础状态),用于显示3 个视图。
TrainSchedule.mxml
-
<?xml version= "1.0" encoding= "utf-8" ?>
-
<mx :WindowedApplication
-
xmlns :mx= "http://www.adobe.com/2006/mxml"
-
xmlns :control= "com.example.control.*"
-
xmlns :business= "com.example.business.*"
-
xmlns :view= "com.example.view.*"
-
pageTitle= "列车时刻表查询"
-
currentState= "{model.currentState}"
-
verticalAlign= "middle" viewSourceURL= "srcview/index.html" >
-
-
<mx :Script >
-
<! [CDATA [
-
import com.example.model.TrainModelLocator;
-
[Bindable ]
-
private var model : TrainModelLocator = TrainModelLocator.getInstance ( );
-
] ] >
-
</mx :Script >
-
-
<mx :Style source= "style.css" />
-
-
<business :Services id= "services" />
-
<control :TrainController id= "controller" />
-
-
<mx :states >
-
<mx :State name= "resultByTrainName" >
-
<mx :RemoveChild target= "{searchForm}" />
-
<mx :AddChild position= "lastChild" >
-
<view :SearchResultByTrainName />
-
</mx :AddChild >
-
</mx :State >
-
<mx :State name= "resultByStationList" >
-
<mx :RemoveChild target= "{searchForm}" />
-
<mx :AddChild position= "lastChild" >
-
<view :SearchResultByStationList />
-
</mx :AddChild >
-
</mx :State >
-
</mx :states >
-
-
<view :SearchForm id= "searchForm" />
-
-
</mx :WindowedApplication >
建立服务调用类:
Services.mxml
-
<?xml version= "1.0" encoding= "utf-8" ?>
-
<business :ServiceLocator
-
xmlns :mx= "http://www.adobe.com/2006/mxml"
-
xmlns :business= "com.adobe.cairngorm.business.*" >
-
-
<mx :Script >
-
<! [CDATA [
-
import com.example.model.TrainModelLocator;
-
] ] >
-
</mx :Script >
-
-
<mx :WebService id= "trainService" wsdl= "{TrainModelLocator.getInstance().wsWSDL}" showBusyCursor= "true" useProxy= "false" >
-
-
<mx :operation name= "getDetailInfoByTrainCode" resultFormat= "xml" >
-
<mx :request >
-
<TrainCode > {TrainModelLocator.getInstance ( ).currentTrain. name } </TrainCode >
-
<UserID > { "" } </UserID >
-
</mx :request >
-
</mx :operation >
-
-
<mx :operation name= "getStationAndTimeByStationName" resultFormat= "xml" >
-
<mx :request >
-
<StartStation > {TrainModelLocator.getInstance ( ).startStation } </StartStation >
-
<ArriveStation > {TrainModelLocator.getInstance ( ).arriveStation } </ArriveStation >
-
<UserID > { "" } </UserID >
-
</mx :request >
-
</mx :operation >
-
-
</mx :WebService >
-
-
</business :ServiceLocator >
代理
然后建立两个代理,分别用于调用WebService服务和本地数据库查询服务:
TrainDelegateWS.as
-
package com.example.business
-
{
-
import com.adobe.cairngorm.business.ServiceLocator;
-
-
import mx.rpc.IResponder;
-
-
public class TrainDelegateWS {
-
public function TrainDelegateWS (responder : IResponder ) {
-
this.service = ServiceLocator.getInstance ( ).getWebService ( "trainService" );
-
this.responder = responder;
-
}
-
-
public function getTrainDetail ( ) : void {
-
call.addResponder ( responder );
-
}
-
-
public function getStationDetail ( ) : void {
-
call.addResponder ( responder );
-
}
-
-
private var responder : IResponder;
-
-
}
-
}
TrainDelegateDB.as
-
package com.example.business
-
{
-
import com.example.model.TrainModelLocator;
-
-
import flash. data.SQLConnection;
-
import flash. data.SQLResult;
-
import flash. data.SQLStatement;
-
import flash.events.SQLErrorEvent;
-
import flash.events.SQLEvent;
-
import flash.filesystem.File;
-
-
import mx.collections.ArrayCollection;
-
import mx.controls.Alert;
-
import mx.rpc.IResponder;
-
public class TrainDelegateDB {
-
private var con :SQLConnection;
-
private var conForStation :SQLConnection;
-
private var file :File = File.applicationDirectory.resolvePath ( "data/TrainsInfo.db" );
-
private var selectStmt :SQLStatement;
-
-
public function TrainDelegateDB (responder : IResponder ) {
-
this.responder = responder;
-
con = new SQLConnection ( );
-
conForStation = new SQLConnection ( );
-
con. addEventListener (SQLEvent. OPEN,openHandler );
-
con. addEventListener (SQLErrorEvent. ERROR,errorHandler );
-
conForStation. addEventListener (SQLEvent. OPEN,openHandlerByStation );
-
conForStation. addEventListener (SQLErrorEvent. ERROR,errorHandler );
-
}
-
-
public function getTrainDetail ( ) : void {
-
con.openAsync (file );
-
}
-
-
public function getStationDetail ( ) : void {
-
conForStation.openAsync (file );
-
}
-
-
private var responder : IResponder;
-
-
-
private function openHandler (e :SQLEvent ) : void {
-
selectStmt = new SQLStatement ( );
-
selectStmt.sqlConnection = con;
-
selectStmt. addEventListener (SQLEvent.RESULT, selectResult );
-
var sql : String = "SELECT * FROM TrainStation WHERE TrainName = '" +TrainModelLocator.getInstance ( ).currentTrain. name + "'";
-
selectStmt. text = sql;
-
selectStmt.execute ( );
-
}
-
private function openHandlerByStation (e :SQLEvent ) : void {
-
selectStmt = new SQLStatement ( );
-
selectStmt.sqlConnection = conForStation;
-
selectStmt. addEventListener (SQLEvent.RESULT, selectResultByStation );
-
var sql : String = "SELECT * FROM TrainStation WHERE StationName = '" +TrainModelLocator.getInstance ( ).startStation + "' or StationName = '" +TrainModelLocator.getInstance ( ).arriveStation + "'";
-
selectStmt. text = sql;
-
selectStmt.execute ( );
-
}
-
private function errorHandler (e :SQLErrorEvent ) : void {
-
Alert. show (e. error. message );
-
Alert. show (e. error.details );
-
}
-
private function selectResult (event :SQLEvent ) : void {
-
var result :SQLResult = selectStmt.getResult ( );
-
if (result. data != null ) {
-
var model : TrainModelLocator = TrainModelLocator.getInstance ( );
-
model.currentTrain.journey = new ArrayCollection ( );
-
nodeItem.num = count;
-
count ++;
-
nodeItem.TrainStation = item.StationName;
-
nodeItem.ArriveTime = item.ArriveTime;
-
nodeItem.StartTime = item.LeaveTime;
-
nodeItem.KM = item.Distance;
-
model.currentTrain.journey.addItem (nodeItem );
-
}
-
model.currentState = "resultByTrainName";
-
} else {
-
Alert. show ( "对不起,没有找到可用数据" );
-
}
-
con. close ( );
-
}
-
private function selectResultByStation (event :SQLEvent ) : void {
-
var result :SQLResult = selectStmt.getResult ( );
-
if (result. data != null ) {
-
var model : TrainModelLocator = TrainModelLocator.getInstance ( );
-
model.currentStaionList.trainStationList = new ArrayCollection ( );
-
if (item.TrainName == result. data [i ].TrainName && item.StationName != result. data [i ].StationName ) {
-
nodeItem.TrainCode = item.TrainName;
-
//计算始发站
-
nodeItem.StartStation = model.startStation;
-
nodeItem.StartTime = "点击查看详情";
-
nodeItem.ArriveStation = model.arriveStation;
-
nodeItem.ArriveTime = "点击查看详情";
-
if (model.currentStaionList.trainStationList [j ].TrainCode == item.TrainName ) {
-
hasNode = true;
-
break f;
-
}
-
}
-
if ( !hasNode ) model.currentStaionList.trainStationList.addItem (nodeItem );
-
}
-
}
-
}
-
model.currentState = "resultByStationList";
-
} else {
-
Alert. show ( "对不起,没有找到可用数据" );
-
}
-
con. close ( );
-
}
-
}
-
}
(未完待续)