学习使用RIA Framework Flex创建MySQL管理UI(初学Flex实例教程)
引言:一直想學習Flex來著,平時都是因為太懶的緣故,沒有去實踐,在csdn上無意看到這篇博文,覺得對自己挺有幫助的,就引過來了~
?
PHPMyAdmin的出現震撼了業界,這毫無疑問。它當然是基于PHP的最佳應用程序,因為它將MySQL管理界面由命令行的形式改為了web瀏覽器的形式。不過,雖然它的功能很強大,但使用并不太方便,界面也不夠美觀。因此,我嘗試通過Rich Internet Application框架設計更理想的MySQL前臺管理程序。
要達成此目標本可選用Ajax。但我不想處理客戶端的不兼容問題。當然,Silverlight也是不錯的選擇,但它仍不夠成熟。之所以選擇Adobe Flex,是因為它擁有富用戶接口工具集和方便的web服務集成功能,而且它生成的Flash應用程序能夠以相同方式在任何操作系統中運行。
我學習了很多有關創建應用程序方面的知識:如何為PHP程序創建安全的SQL web服務;如何通過Flex訪問web服務;如何將web服務返回的數據輸入數據網格中并顯示。在本文中,我將引領讀者從前臺到后臺,逐步創建MySQL管理程序。讀者從中可了解一些有用的信息,以創建自己的Rich Internet應用程序。
創建后臺程序
Flex應用程序擅長與web服務通訊,以發出請求及提交數據。因此,首先需要創建一個非常簡單的PHP腳本,它將以XML格式返回數據庫列表、表或表中的數據。
清單 1. req.php
<?php
require_once("MDB2.php");
$sql = 'SHOW DATABASES';
if ( $_REQUEST['mode'] == 'getTables' )
$sql = 'SHOW TABLES';
if ( $_REQUEST['mode'] == 'getData' )
$sql = 'SELECT * FROM '.$_REQUEST['table'];
$dsn = 'mysql://root@localhost/'.$_REQUEST['db'];
$mdb2 =& MDB2::factory($dsn);
if (PEAR::isError($mdb2)) { die($mdb2->getMessage()); }
$dom = new DomDocument();
$dom->formatOutput = true;
$root = $dom->createElement( "records" );
$dom->appendChild( $root );
$res =& $mdb2->query( $sql );
if (PEAR::isError($mdb2)) { die($mdb2->getMessage()); }
while ($row = $res->fetchRow(MDB2_FETCHMODE_ASSOC))
{
$rec = $dom->createElement( "record" );
$root->appendChild( $rec );
foreach( array_keys( $row ) as $key ) {
$key_elem = $dom->createElement( $key );
$rec->appendChild( $key_elem );
$key_elem->appendChild( $dom->createTextNode( $row[$key] ) );
}
}
$res->free();
$mdb2->disconnect();
header( "Content-type: text/xml" );
echo $dom->saveXML();
?>
該腳本的第一項工作就是利用MDB2庫連接數據庫。如果沒有安裝MDB2庫,則可使用PEAR安裝該庫,如下所示:
% pear install MDB2
%
如果PEAR無法正常運行,可訪問http://pear.php.net/mdb2,然后下載源代碼并將其解包到PHP的include路徑下。MDB2是通用的數據庫適配器層,它已取代了廣為使用的PEAR DB庫。
腳本的第二項工作就是創建XML DOM Document對象,該對象將用來創建要輸出的XML樹。從此處開始,它將運行查詢,并在XML樹中添加row和column作為XML標簽。最后,該腳本將關閉所有連接,并將XML保存到PHP輸出流中。
選用XML DOM對象的原因是,它可避免任何與數據、不對稱標簽等有關的編碼問題以及各種可能使XML產生混亂的因素。我可以將調試XML數據流的時間節省下來做其他許多更有意義的工作。您一定也會這樣做。
將該腳本安裝到本地機器上的可運行目錄下,然后使用curl命令向服務器發出請求。
% curl "http://localhost/sql/req.php"
<?xml version="1.0"?>
<records>
<record>
<database>addresses</database>
</record>
<record>
<database>ajaxdb</database>
</record>
...
%
在本例中,我并未指定數據庫或模式,這會要求腳本返回可用數據庫的清單。假如web服務腳本有權執行該任務,則在curl語句后面就會顯示執行的結果。在本例中,將以標簽的形式顯示不同數據庫的列表。
該腳本返回的所有數據都帶有<records>標簽,它包含一組<record>標簽。每個<record>標簽的名稱和內容取決于已執行的SQL語句。在本例中,只返回單列命名數據庫。
除了使用curl命令,還可將URL輸入瀏覽器中,然后在加載頁面后選擇“View Source(查看源文件)”。
在下例中,將連接articles數據庫并獲取它的表格列表。結果如下:
% curl ".../req.php?mode=getTables&db=articles"
<?xml version="1.0"?>
<records>
<record>
<tables_in_articles>article</tables_in_articles>
</record>
</records>
%
articles數據庫中只有一個名為article的表格,這并不奇怪。要運行經典的select * from article查詢以獲取所有記錄,可使用以下URL:
% curl ".../req.php?mode=getData&db=articles&table=article"
<?xml version="1.0"?>
<records>
<record>
<id>1</id>
<title>Apple releases iPhone</title>
<content>Apple Computer is going to release the iPhone...</content>
</record>
<record>
<id>2</id>
<title>Google release Gears</title>
<content>Google, Inc. of Mountain View California has...</content>
</record>
</records>
%
表格中有兩條記錄:第一條顯示Apple公司將發布超炫的IPhone;第二條顯示Google公司將發布同樣很炫、但用途完全不同的Gears系統。
在本地機器上安裝了極為強大且靈活的后臺程序后,就可以著手為其創建Flex前臺程序了。
創建用戶界面
我想以層的形式創建Flex應用程序,首先是用戶界面,然后在框架中添加代碼以實現互動性。首先,若尚未安裝Flex SDK則先安裝。Flex SDK是免費軟件,Flex Builder 2 IDE也有免費試用版。可從http://www.flex.org/download下載Flex SDK。Flex SDK是免費的,Flex 3 SDK也將成為開源軟件。Flex Builder是一種基于Eclipse的開發環境,通過拖放控件即可創建界面,但本例不必使用該工具。我非常喜歡使用標簽,因此通常采用代碼視圖并直接修改MXML。
我想在界面頂部放置幾個控件并在底部放置一個數據網格,以顯示表中的數據。頂部的控件就是兩個下拉列表,可在其中選擇數據庫和表。
該窗體的MXML如清單2所示。
清單 2. flexmysql1.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
<mx:VBox horizontalAlign="left">
<mx:HBox>
<mx:Label text="Database:" />
<mx:ComboBox id="selectedDatabase" width="381" height="21">
</mx:ComboBox>
</mx:HBox>
<mx:HBox>
<mx:Label text="Table:" />
<mx:ComboBox id="selectedTable" width="381" height="21">
</mx:ComboBox>
</mx:HBox>
<mx:DataGrid id="dg1" width="452">
</mx:DataGrid>
</mx:VBox>
</mx:Application>
在Flex Builder 2中編譯及運行這段代碼時,結果如圖1所示。
圖1.界面布局
相當整潔,對吧?漸變背景很漂亮,控件也很美觀。我只做了極少量的工作。當然,圖形設計師也可添加一些修飾,以使其更加美觀,例如過渡效果和圖像。而我還是喜歡整潔的界面,并要確保它在每臺客戶機上都具有一致的外觀和表現,而Ajax應用程序要做到這一點并不容易。
獲取數據庫清單
補充Flex應用程序代碼的第一步就是,當應用程序加載后在窗體頂部顯示數據庫的組合框。相關代碼如清單3所示。
清單 3. flexmysql2.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
initialize="onInitialize()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
private static const SERVICE_BASE:String = "http://localhost/sql/req.php";
public function onInitialize():void
{
myservice.url = SERVICE_BASE;
myservice.send( null );
} public function onResult(event:Event):void
{
selectedDatabase.dataProvider = myservice.lastResult..database.*;
}
]]>
</mx:Script>
<mx:HTTPService id="myservice" result="onResult(event)" resultFormat="e4x">
</mx:HTTPService>
<mx:VBox horizontalAlign="left">
<mx:HBox>
<mx:Label text="Database:" />
<mx:ComboBox id="selectedDatabase" width="381" height="21">
</mx:ComboBox>
</mx:HBox>
<mx:HBox>
<mx:Label text="Table:" />
<mx:ComboBox id="selectedTable" width="381" height="21">
</mx:ComboBox>
</mx:HBox>
<mx:DataGrid id="dg1" width="452">
</mx:DataGrid>
</mx:VBox>
</mx:Application>
我省略了與前例類似的部分代碼,以縮短代碼段長度。差別重點在于<mx:HTTPService>標簽,它將創建HTTP Service Flex對象,而后者將與服務器進行通訊。該服務對象由onInitialize方法調用,而后者在Flex應用程序啟動時調用。onInitialize方法先設置服務的URL,然后開始發出請求。請求完成后,就調用onResult方法。onResult方法將組合框的dataProvider設為web服務器的返回結果。
該方法最有價值的部分如下:
myservice.lastResult..database.*
看看這個語句。如果之前不了解E4X的作用,我可以稍加解釋。myservice.lastResult變量實際上是一個XML文檔。‘..’句法等價于XPath ‘//’句法。它表示“將具有此名字的任何一個標簽給我”,在本例中就是“將任何一個數據庫標簽給我”。星號表示數據庫標簽的任何子標簽。由于數據庫標簽只有一個子標簽,即數據庫名稱的文字部分,因此這段代碼就表示“將XML文檔中每個數據庫的名稱給我”。這個功能真的很好用!
正是由于ActionScript的這種E4X擴展,Flex才能夠方便地與XML數據源進行通訊。據我所知,還沒有其他語言能夠如此方便地查詢XML文檔。因此利用強大的E4X,就可以在瀏覽器中運行該應用程序,并得到如圖2所示的結果。
圖2.填充數據庫名稱的數據庫組合框
單擊該組合框時,將彈出下拉列表,并顯示機器中的數據庫列表。是的,其中有很多數據庫。幾乎每篇有關PHP、Flex、Rails或其他技術的文章都會用到數據庫,所以我擁有大量的數據庫。
創建表視圖代碼
創建示例Flex應用程序的最后一步就是添加表格的下拉菜單,并在數據網格中顯示選中表格的數據。該例的完整代碼如清單4所示。
清單 4. flexmysql.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
initialize="onInitialize()">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
private static const SERVICE_BASE:String = "http://localhost/sql/req.php";
private var loadingDatabases:Boolean = true;
private var loadingTables:Boolean = false;
public function onInitialize():void
{
loadingDatabases = true;
myservice.url = SERVICE_BASE;
myservice.send( null );
} public function onResult(event:Event):void
{
if ( loadingDatabases )
{
loadingDatabases = false;
selectedDatabase.dataProvider = myservice.lastResult..database.*;
onSelectDatabase();
}
else if ( loadingTables )
{
loadingTables = false;
var tables:Array = new Array();
for each ( var tablRecord:XML in myservice.lastResult..record )
{
for each( var tablCol:XML in tablRecord.* )
tables.push( tablCol..*.toString() );
}
selectedTable.dataProvider = tables;
onSelectTable();
} else
{
var records:Array = new Array();
for each ( var record:XML in myservice.lastResult..record )
{
var outRecord:Array = new Array();
for each( var column:XML in record.* )
outRecord[ column.name() ] = column..*.toString();
records.push( outRecord );
}
var data:ArrayCollection = new ArrayCollection( records );
dg1.dataProvider = data;
}
} public function onSelectDatabase():void
{
loadingDatabases = false;
loadingTables = true;
var http://www.cnblogs.com/fjytzh/admin/String = SERVICE_BASE;
url += "?mode=getTables&db="+selectedDatabase.selectedLabel;
myservice.url = url;
myservice.send(null);
} public function onSelectTable():void
{
var http://www.cnblogs.com/fjytzh/admin/String = SERVICE_BASE;
url += "?mode=getData&db="+selectedDatabase.selectedLabel;
url += "&table="+selectedTable.selectedLabel;
myservice.url = url;
myservice.send(null);
}
]]>
</mx:Script>
<mx:HTTPService id="myservice" result="onResult(event)" resultFormat="e4x">
</mx:HTTPService>
<mx:VBox horizontalAlign="left">
<mx:HBox>
<mx:Label text="Database:" />
<mx:ComboBox id="selectedDatabase" width="381" height="21"
change="onSelectDatabase()">
</mx:ComboBox>
</mx:HBox>
<mx:HBox>
<mx:Label text="Table:" />
<mx:ComboBox id="selectedTable" width="381" height="21"
change="onSelectTable()">
</mx:ComboBox>
</mx:HBox>
<mx:DataGrid id="dg1" width="452">
</mx:DataGrid>
</mx:VBox>
</mx:Application>
其中有一處重要修改,即添加了onSelectDatabase()函數的代碼,以獲取表格列表,然后將其輸入到onResult()函數中,還添加了onSelectTable()函數,該函數可檢索表格中的數據,并在onResult()處理器中設置數據網格。
在瀏覽器中運行該例時,結果如圖3所示。
圖3. 運行“show tables”查詢之后的結果
本例中使用了nasa數據庫,這是我為NASA Ames演講而創建的數據庫(我用了“火箭科學”的笑話,因為當時我的聽眾是一群火箭科學家)。該數據庫只有一個名為mission的表,其中包含兩列,分別代表每項由NASA發起但已撤消的任務名稱和年份。
在數據網格中單擊名稱列即可按名稱排序,如圖4所示。
圖 4. 顯示mission表中的數據
然后單擊年份列,以按照年份排列數據,如圖5所示。
圖 5. 迪斯科球式查詢
在過去幾年中,我們似乎并未發起任何任務。
后續步驟
至此,本例已可應用于許多場合。在前臺Flex應用中,可以添加一些對用戶更友好的控件,以添加、刪除或更新表格。甚至可以提供數據過濾功能或者編輯功能,以修改表格中的數據。數據網格控件非常強大,可以處理現場編輯任務。也可以用在完全不同的場合,例如使用Flex繪圖軟件包執行數據分析和可視化工作。
總結
PHP和Flex的結合潛力無限。利用PHP可以方便地在后臺發布web服務,可以單獨發布,可以與HTML前臺程序一起發布。PHPMyAdmin帶有web服務接口擴展功能,使任何人都能以Flex、Ajax、Silverlight、桌面小部件或其他任何技術編寫前臺程序。Flex為PHP開發人員提供了強大的前臺工具。它避開了困擾Ajax開發人員的客戶端不兼容問題。Flex 2并非只能使用特定的服務器技術,因此Flex應用程序編譯完成后,它就可以部署在任何場合,因為它只是一個SWF文件。可以看到,利用簡單的web服務對象和強大的E4X語言擴展,就可以讓Flex應用程序方便地與幾乎任何一種后臺程序進行通訊。
讀者不妨一試,如果您使用PHP和Flex創建了有趣的程序,請告訴我,也許我們可以合寫一篇文章來介紹它。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/java060515/archive/2008/01/30/2072602.aspx
轉載于:https://www.cnblogs.com/fjytzh/archive/2010/04/02/1703118.html
總結
以上是生活随笔為你收集整理的学习使用RIA Framework Flex创建MySQL管理UI(初学Flex实例教程)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3/15/2010
- 下一篇: 导入shape文件到SDE数据库