flex有多種與後台互動的方法,(/Files/xingluzhe/Flex與Web服務的互動.ppt)這裡有個不錯的介紹。我之前用的是python的django做後台,有些許的收穫,先奉獻出來與大家分享。
首先是Django背景搭建,這個在我的一篇博文中有介紹,這裡我便不再贅述。
其次是flex前台與python背景互動。
1. 建立一.xml設定檔(放在與mxml檔案同目錄下)。設定檔中的內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<services-config>
<services>
<service id="webblogService" class="flex.messaging.services.RemotingService"
messageTypes="flex.messaging.messages.RemotingMessage">
<destination id="webblogapp">
<channels>
<channel ref="webblogChannel"/>
</channels>
<properties>
<source>*</source>
</properties>
</destination>
</service>
</services>
<channels>
<channel-definition id="webblogChannel" class="mx.messaging.channels.AMFChannel">
<endpoint uri="http://localhost:8080/webblog/gateway/" class="flex.messaging.endpoints.AMFEndpoint"/>
</channel-definition>
</channels>
</services-config>
2. 在主mxml檔案中添加如下語句:
<mx:RemoteObject
id="djangoService"
destination="webblogapp" //注意這裡的destination是我用python manage.py startapp webblogapp產生的檔案夾,沒試過用的名稱行不行
showBusyCursor="true">
</mx:RemoteObject>
另外需要注意的是,我的整個工程都只有用到一個RemoteObject。在別的component中應用首頁面中定義的RemoteObject主要使用Application.application.djangoService;就行了。
3. 與後台互動
private var token: AsyncToken;//定義一個token
token = remoteObj.echo(remotefunc, arg); //調用後台資料庫提供的介面echo
token.addResponder(new AsyncResponder(onResultHandle,faultHandler)); //為token添加responder
然後在onResultHandle中做你對後台返回的結果的處理
private function onResultHandle(re:ResultEvent, token:Object=null):void
{
resultHandle(re); //這裡做相應的處理
}
private function faultHandler(fe:FaultEvent, token:Object=null):void
{
trace(fe.fault.faultDetail); //這個函數可以原封照抄,因為當你的後台出錯時,它會在flex console視窗中列印出錯的位置和原因
}
4. 從上面的介紹可以看出,每次調用背景一個方法都會重複執行大致相同的操作,除了調用的方法不一樣。所以為了達到代碼的重用,我寫了個簡單類來負責與背景通訊:/Files/xingluzhe/KCommunication.txt(這個類的代碼)
/////////////////////////////////////////////////////////
// FileName: KCommunication.as
// creator : David(蔡海濱)
// Date : 2009-8-20
// Commment: 主要用於負責前段與背景通訊
/////////////////////////////////////////////////////////
package com.wps
{
import flash.events.EventDispatcher;
import mx.core.Application;
import mx.rpc.AsyncResponder;
import mx.rpc.AsyncToken;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.RemoteObject;
public class KCommunication extends EventDispatcher
{
/**
* @brief 類建構函式
*
*/
public function KCommunication()
{
}
/**
* 設定Token和相應的處理函數
* @param remotefunc 想要調用的遠程函數
* @param arg 要給遠程函數傳遞的參數(都放進一個字串中)
* @param func 與後台互動完後的響應事件
*
*/
public function setTokenAndHandle(remotefunc:String, arg:String, func:Function):void
{
resultHandle = func;
token = remoteObj.echo(remotefunc, arg); //注意,這裡我讓背景介面統一為echo,傳遞的參數都是一個字串
token.addResponder(new AsyncResponder(onResultHandle,faultHandler));
}
/**
* @brief 與後台互動完後的響應事件
* @param re
* @param token
*
*/
private function onResultHandle(re:ResultEvent, token:Object=null):void
{
resultHandle(re);//注意,這裡的這個處理函數,可以在類外提供
}
private function faultHandler(fe:FaultEvent, token:Object=null):void
{
trace(fe.fault.faultDetail);
}
private var remoteObj: RemoteObject = Application.application.djangoService;;
private var resultHandle:Function = null;
private var token: AsyncToken;
}
}
舉個例子吧:
比如要實現登陸的功能
1. import com.KCommunication;
2. private var comm:KCommunication = new KCommunication();
3. private function onConfirm(evt:Event):void
{
//getUser是我在後台定義好的介面,用於返回使用者的使用者名稱,和密碼,這裡validateUserInfo就是對返回結果的處理
comm.setTokenAndHandle("getUser", username.text, validateUserInfo);
}
4. private function validateUserInfo(re:ResultEvent):void
{
if(re.result.length > 0)
{
_name = re.result[0].username.toString();
_pw = re.result[0].password.toString();
_nick = re.result[0].nickname.toString();
if (_name === username.text && _pw === password.text)
{
kgv._username = _name;
kgv._password = _pw;
kgv._nickname = _nick;
username.text = "";
password.text = "";
}
else
{
errorMessage();
}
}
else
{
errorMessage();
}
}
這樣便可以實現通訊。
現在就剩下最後一個疑問了:後台統一介面的實現^_^
def getUser(name):
#return the user
user = Users.objects.filter(username = name[0])
return user
//這是我定義的背景統一的介面
def echo(request, requestFunc, requestArg)://第一個參數是必須的,調用時不用指定,requestFunc是提供給前台的方法,requestArg是字串的參數,
以|->!!!!<-|分隔
#seperate the arguments out at first
arg = requestArg.split('|->!!!!<-|') //分割出所需的參數(這裡所有的參數都是字串,可以安裝需要將字串轉換成所需的參數的類型
return FuncMap[requestFunc](arg) //調用函數,這裡FuncMap是一個Map容器
FuncMap定義如下:
FuncMap = {"getUser": getUser, #when add an interface, register here
}
當添加新的介面時,只需在這裡註冊即可。
----David Cai 2009-08-31 晚於金山公司