第09章 在Flash影片应用程序中处理结果和结果集对象要连接到Java应用程序服务器上的FlashRemotingMX服务并且调用远程服务方法,就必须使用mx.remoting和mx.rpc这两个ActionScript类库:这两个类库包含了所有的FlashRemoting MX for ActionScript 2.0类和方法实现。
其中,mx.remoting是一个十分核心的ActionScript类库,它包含了用来与应用程序服务器建立连接的所有对象及方法,而mx.rpc可以用来调用远程方法并处理结果。
在前面的章节中,我们介绍了如何通过FlashRemotingMX网关服务在JSP网页和Servlet中向Flash影片应用程序传递数据,也介绍了如何使用Flash影片应用程序向JSP网页和Servlet传递参数,并且介绍了如何使用Flash Remoting MX forJava与JDBC结合调用数据库,而且创建了几个简单的例子。
但是,当从JSP网页和Servlet向Flash影片应用程序传递的数据被接收到时,如何处理接收到的结果呢?我们在前面的例子中已经使用了一些方法,这只是在Flash影片应用程序中处理结果丰富方法中最简单的,Flash Remoting MX for ActionScript2.0组件内置了丰富的ActionScript脚本语法用来处理结果。
本章就来详细地介绍一下这些ActionScript脚本语法。
9.4使用DataGlue类处理记录集数据要在一个Flash UI组件中显示RecordSet记录集,一般可以使用该组件内建的setDataProvider()方法或者dataProvider属性,但是如果想在一个Flash UI组件中显示记录集中某一字段下的所有记录,就比较困难了。
例如,在前面的例子中,我们要在一个下拉列表框组件中显示记录集中酒店名,就必须首先创建一个新的单字段记录集,将原记录集中该字段的数据填充新的单字段记录集,然后再使用组件的setDataProvider()方法或者dataProvider属性,显然,这比较麻烦,而且占用的资源也比较多。
为了解决这个问题,Flash RemotingMX还内建了名为DataGlue的ActionScript类。使用DataGlueActionScript类文件也可以在一个FlashUI组件中显示RecordSet记录集。DataGlueActionScript类文件随同Flash RemotingMX组件一起被安装,要使用它,必须导入相应的类库,可以使用下面的一行脚本:
import mx.remoting.DataGlue;
DataGlue类有两个内建的方法:DataGlue.bindFormatStrings()和DataGlue.bindFormatFunction(),使用这两个方法都可以在Flash UI组件(例如组合框和列表框)中显示记录集。
9.4.1使用DataGlue.bindFormatStrings方法绑定记录集可以使用DataGlue.bindFormatStrings()方法在一个FlashUI组件(例如组合框和列表框)中显示RecordSet。下面的一段ActionScript脚本代码将结果RecordSet绑定到名为displayNames的列表框UI组件:
DataGlue.bindFormatStrings(displayNames, result, "#ContactName#", "#customerID#"

;
在这一段代码中,后两个参数被传递给函数(#ContactName#和#customerID#是记录集的字段名)。当用户选择组件中一个特殊的纪录时,ContactName列被显示在UI组件中,而customerID列被返回。下面,我们来改造一下前面的例子,看一下如何使用DataGlue类。
1打开前面一章我们创建的Restaurant_component.fla文档,将文档另存为Restaurant_component_DataGlue.fla;
2保持当前位于主时间轴编辑状态,修改主时间轴上的脚本代码。在”动作”面板上追加下面的一行脚本代码:
import mx.remoting.DataGlue;
3在舞台上双击影片剪辑元件实例main_mc,使影片剪辑元件main处于编辑状态,选中层Script。保持该层被选中,在“动作”面板上修改其中的脚本代码:
将下面的一段脚本代码:
var newRecordSet:RecordSet = new RecordSet(["hotelName"]);
for (var i = 0; i<resultRecordSet.length; i++) {
newRecordSet.addItemAt(i, {hotelName:resultRecordSet.getItemAt(i).hotel_name});
}
if (newRecordSet.isLocal()) {
newRecordSet.addItemAt(0, {hotelName:"请选择一个酒家或酒店"});
hotelName_cb.dataProvider = newRecordSet;
}
替换为
DataGlue.bindFormatStrings(hotelName_cb, resultRecordSet, "#hotel_name#", "#hotel_name#"

;
可以看到,前面多行代码实现的功能,现在只需一行就可以实现了。
4因为现在是使用DataGlue类,所以对于UI组件的读取方式也应该改变一下。在本例中,这段脚本代码位于函数applyFilter()体内:
将下面的一段脚本代码
list_lb.dataProvider = resultRecordSet.filter(thisFilter, hotelName_cb.selectedItem["hotelName"]);
替换为
list_lb.dataProvider = resultRecordSet.filter(thisFilter, hotelName_cb.selectedItem.label);
5最后可以测试一下效果,可以看到与前面的例子功能相同。
9.5使用RemotingConnector组件和数据绑定RemotingConnector是Flash的一个数据组件,使用该组件你可以非常轻松的建立与远程服务的连接——该远程服务必须是通过FlashRemotingMX网关提供——并且可以调用远程服务所定义的方法函数,使用它只需要将该组件拖放到舞台上并定义组件参数,而且可以使用Flash的数据绑定功能。
我们在这里要介绍的是首先是通过编写脚本代码的方式使用RemotingConnector组件。
9.5.1编写脚本代码使用RemotingConnector组件要通过编写脚本代码的方式使用该组件,也必须首先在开始将RemotingConnector组件拖放到当前舞台上(或者只要在库中就可以了),然后才能开始编写代码使用该组件,这是使用该组件的第一步。
另外,在编写脚本代码时要导入RemotingConnector类,这是使用该组件编写脚本代码的第一步,可以使用下面的脚本语句:
import mx.data.components.RemotingConnector;
下面我们就使用一个例子来看一下怎样使用该组件。
1打开前面一节我们创建的Restaurant_component.fla文档,将文档另存为Restaurant_component_RC.fla;
2保持文档处于主时间轴的编辑状态,改变主时间轴上的脚本代码如下:
stop();
//-------------------------------------------------------------
//导入RemotingConnector类
import mx.data.components.RemotingConnector;
//构造RemotingConnector组件实例并定义实例属性
var my_rc:RemotingConnector = new RemotingConnector();
my_rc.addEventListener("result", returnRowSet_Result);
my_rc.addEventListener("status", returnRowSet_Status);
my_rc.gatewayUrl = "http://localhost:8080/3JK/gateway";
my_rc.methodName = "returnRowSet";
my_rc.serviceName = "3JK";
my_rc.suppressInvalidCalls = true;
function GetRestaurantInfo():Void {
if (selectedhotel_name == undefined&&selectedhotel_flavor == undefined &&selectedhotel_location ==undefined) {
//定义参数为空
my_rc.params = null;
//触发连接,调用远程服务方法
my_rc.trigger();
} else {
//定义传递给远程服务方法的参数
my_rc.params ={hotel_name:selectedhotel_name,hotel_flavor:selectedhotel_flavor,hotel_location:selectedhotel_location};
//触发连接,调用远程服务方法
my_rc.trigger();
selectedhotel_name = "正在加载数据";
}
}
function returnRowSet_Result(ev

bject) {
//接收结果
main_mc.list_lb.removeAll();
main_mc.list_lb.dataProvider = ev.target.results;
selectedhotel_name = "";
fetchOK = 1;
main_mc.resultRecordSet = ev.target.results;
}
function returnRowSet_Status(stat

bject) {
//接收错误
trace("接收到错误"

;
}
//初始化
function ini():Void {
if (this.inited != undefined) {
return;
} else {
var inited:Boolean = true;
GetRestaurantInfo();
}
}
ini();
3打开组件面板,将RemotingConnector组件拖放到舞台上创建一个实例(实际,只需放到库中就可以了)。
最后可以测试一下效果,可以看到与前面的例子功能相同。