Luar's Flash Playground:利用amfphp傳送Data到Flex2 Tree組件
利用amfphp傳送Data到Flex2 Tree組件 (07-04-2007)

這篇教程,主要講解怎樣使用amfphp 1.9開始支援的AMF3跟Flex2進行Remoting通訊,將Database的多層樹狀結構Data傳到SWF,利用Tree組件表演出來。

學習重點:

  • 設計多層樹狀結構的Database Table
  • 編程Flex2可以直接套用amfphp返回數據格式
  • 利用Flex Builder開發amfphp專案

[示範][下載Source File]

教程會以最簡單、直接的原則去講解,深入重要技術細節,略去其他枝節,務求使人最快掌握基本開發概念。

安裝整個開發專案

解壓到Folder叫flexTree後,打開Flex Builder,File>Import...,選「Existing Projects into Workspace」,按「Next」,在Select root directory:一行,按「Browse...」,選擇解壓後Folder flexTree,按「確定」,按「Finish」便可。

安裝完成品

在Source File中已經有一個flexTree.sql,先在MySQL Database test建立一個Table。打開flexTree/bin/amfphp/services/FlexTree/inc/config.php,修改Database連接設定。

如果安裝整個開發專案,在Web Server建立Virtual Directory,名稱叫flexTree,指向flexTree/bin Folder。

如果想在自己機器先安裝體驗一下,可以將bin裡面的Files(已含amfphp)解壓到Web Root/flexTree下(不包括bin這Folder),在Browser打開http://localhost/flexTree/index.html就可以看到。

設計Database Table

怎樣設計Database Table來支援無限樹狀層數?原理很簡單,不需要多個Tables,只要一個便足夠。

CREATE TABLE `flextree` (
  `id` int(5) unsigned NOT NULL auto_increment,
  `label` varchar(15) NOT NULL default '',
  `data` varchar(15) default NULL,
  `parentid` int(5) unsigned default NULL,
  `hier` tinyint(3) unsigned default NULL,
  `hierindent` tinyint(3) unsigned NOT NULL default '0',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
label是標籤、data是標籤代表數據,兩者主要給傳到Tree組件。parentid是該節點的父層,如果是最根本的節點,parentid就是NULL。hierindent是深入去幾多層,最根本的節點是0,它的子節點是1,孫節點是2。hier是標籤在該層排列次序。

amfphp結構

打開flexTree/bin/amfphp/gateway.php,第103行:

include "core/amf/app/Gateway.php";
因為amfphp的程式直接放在專案運作的Folder下,所以路徑是以上這樣(這也是default設定)。如果你打算安裝amfphp核心程式在公用Folder給不同專案共用,而不是每個專案都有自己一份amfphp,請修改這裡(支援絕對硬碟路徑C:\amfphp或網路相對路徑)。

設定Services路徑,第113行:

$gateway->setBaseClassPath("services/");
amfphp將要呼叫的程式放在哪裡,default是gateway.php所在Folder\services下,建議各專案有自己的services Folder。

設定編碼,支援雙字節,第121行:

$gateway->setCharsetHandler("iconv", "UTF-8", "UTF-8");
將編碼設定為UTF-8,整個專案,由Database到SWF,都是UTF-8,完全支援中文。

Service位置

本專案Service Files會以放在flexTree/bin/amfphp/services/FlexTree下,暫時只有一個Class,就是同名FlexTree.php,其他關於Database連接的輔助及設定Files,則放在inc下。打開inc/config.php,可以修改Database連接設定。

編寫一個可以供amfphp呼叫的Class

打開FlexTree.php作參考,現在amfphp已經可以不用設定Method Table,Class裡所有Function都可以被呼叫,如果不想被amfphp呼叫,可以加「_」在Function名稱前,就會當作Private Method,不能被外面呼叫。例如FlexTree.php裡的_genArray()。

amfphp傳回Data格式

FlexTree.php第15行,一般情況,SQL查詢結果,可以以Recordset通過amfphp傳給SWF,便能夠直接傳到DataGrid組件。但是,如果要在Flex MXML那邊不用作任何編程上再Serialization,能夠直接將Data傳到Tree組件的話,需要在PHP整理好一個Associate Array。

因為Database Table設計得宜,所以可以簡單地將它轉為Associate Array。Tree組件接受的Array Index名稱為label和data,子層的Array Index名稱必須是children:

array_push($s, array('label' => $label[$catid], 'data' => $data[$catid], 'children' => $this->_genArray($subcats[$catid], $subcats, $label, $data)));
所以Database Table的Field名稱不一定是label和data,最重要是將SQL查詢結果轉為Associate Array時,index名稱一定要是label、data和children。

MXML編程

我的Flex專案結構,習慣將mxml等Source Files放在src下,bin就是Default compile好東西放置地方,同時也是將來會上傳Server的東西。其他需要上傳Server的東西而不跟Flex有關,例如amfphp程式和Services程式,也一併先放到bin下。

打開flexTree/src/index.mxml作參考(我習慣將主MXML名為index.mxml,因為Flex Builder產生的HTML wrapper也會名為index.html,上傳到Server後,便可以在網址路徑直接打開,不用再加index.html)。index.mxml很簡單,重點留意地方有幾個。

<mx:RemoteObject>就是用來連接amfphp的tag:

<mx:RemoteObject showBusyCursor="true" destination="FlexTree" source="FlexTree.FlexTree" id="vo">
destination是Class名稱,例如本專案為FlexTree,source是Service完整路徑名稱,因為FlexTree.php是放在Folder FlexTee下,所以是「FlexTree.FlexTree」。例如放在Folder sample下,就是「sample.FlexTree」。id是這個RemoteObject名稱,方便別人呼叫。

在<mx:RemoteObject>裡加上本mxml打算呼叫的function名稱,例如「getList」:

<mx:method name="getList" result="tree.dataProvider=event.result"/>

這個例子的流程是這樣:當SWF下載和初始化後,<mx:Application> tag裡的creationComplete="vo.getList()"就會自動執行。如果Function需要帶參數,可以在getList()裡加上,例如TextInput.text:

getList(textinput.text, 'string', true)

amfphp傳回結果,result被觸發,Data會在event.result裡,所以將tree的dataProvider指向event.result,便能夠直接將結果顯示出來。

Remoting自家gateway.php路徑設定

Flex Builder通過兩個XML Files將自家gateway.php路徑在編譯時加到SWF裡。打開flexTree/src/services-config.xml,第8行:

<endpoint uri="amfphp/gateway.php" class="flex.messaging.endpoints.AMFEndpoint"/>
uri設定gateway.php路徑,以上是相對路徑寫法,即SWF執行所在Folder下的amfphp/gateway.php。

如果要設定其他路徑,可以以絕對路徑寫法,例如:

uri="http://{server.name}:{server.port}/{context.root}/amfphp/gateway.php"
{server.name},{server.port}等於SWF執行所在domain,至於{context.root}即SWF執行所在Folder名稱,這裡用{context.root}這變數代表。你也可以Hard Code一個Folder名稱,但是如果用{context.root}這變數,必須在Flex Builder設定Compiler Arguments,否則會報錯,不能編譯。

打開flexTree/src/remoting-config.xml,所有mxml裡有需要用到的Class都要在這裡設定,每一個以destination node包含,id則是Class名稱:

<destination id="FlexTree">
  <properties>
    <source>*</source>
  </properties>
</destination>

設定Flex Builder的Compiler Arguments

在Flex Builder Navigator Panel(即列出目前開發中專案的Panel),在flexTree旁Right Click選Properties,選Flex Compiler,在Additional compiler arguments加-services services-config.xml,因為兩個XML files是在index.mxml放在同一個Folder,所以不用加路徑。

-locale en_US -services services-config.xml
如果在services-config.xml用了{context.root},則要再加-context-root flexTree,否則不用了。

總結

只要弄清楚amfphp傳回格式,與及一切路徑設定上的瑣碎事,用amfphp和Flex開發RIA,真的很簡單容易,只不過是Flex Builder Design View組件的鋪排和懂SQL語法就可。

本文章由發表。
意見
"; print "沒有意見。
 "; } ?>
  • 本来准备使用OpenAmf的,这样后台都统一使用java。但amfphp的C extention效率实在太诱人了。
    徘徊中...

    黑羽於07-04-2007發表

  • 感謝你提供flex2 Tree source,上帝祝福你^^

    余衡道於21-05-2007發表

  • 那如何用一個button來建立一個資料夾跟檔案呢?!抱歉,因為是新手還在摸索!!

    由慎於09-07-2007發表

  • 之前使用了amfphp 1.8,在大陆也有人使用amfphp和flex作了一个mysql查阅工个!。。。 看到这个有详细的注解,真是精彩,谢谢!

    korpton於04-08-2007發表

同組文章