从动态 HTTPService 异步获取数据以填充 Advanced Data Grid Flex
Posted
技术标签:
【中文标题】从动态 HTTPService 异步获取数据以填充 Advanced Data Grid Flex【英文标题】:Get data from dynamic HTTPService Asynchronous to populate an Advanced Data Grid Flex 【发布时间】:2010-12-30 10:36:35 【问题描述】:我必须填充具有以下字段的高级数据网格: 大陆->国家->社会-->实际价值-->估计价值 我想模拟一个金融市场,所以我必须通过来自 HTTPService 的异步请求来更改一些值;你有什么想法吗? 谢谢你。 如有必要,我会发布 .as 文件,但它是由 Flex Builder 自动生成的。
这是客户端 Flex/Air 应用程序的代码:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
pageTitle="prova"
creationComplete="initApp()" backgroundGradientColors="[#ffffff, #ffffff]">
<mx:ViewStack id="applicationScreens" >
<mx:Canvas id="view" >
<mx:AdvancedDataGrid id="dataGrid" initialize="gc.refresh();"
borderColor="#000000"
selectionMode="singleRow"
rowCount="8"
editable="false"
lockedColumnCount="1"
right="10" left="10" top="10" bottom="71" itemClick="adg_itemClick(event);">
<mx:dataProvider>
<mx:GroupingCollection id="gc" source="dataArr">
<mx:grouping>
<mx:Grouping>
<mx:GroupingField name="continenteCol">
<mx:summaries>
<mx:SummaryRow summaryPlacement="group">
<mx:fields>
<mx:SummaryField dataField="actualCol"
operation="SUM"/>
<mx:SummaryField dataField="estimateCol"
operation="SUM"/>
</mx:fields>
</mx:SummaryRow>
</mx:summaries>
</mx:GroupingField>
<mx:GroupingField name="statoCol">
<mx:SummaryRow summaryPlacement="group">
<mx:fields>
<mx:SummaryField dataField="actualCol"
operation="SUM" />
<mx:SummaryField dataField="estimateCol"
operation="SUM"/>
</mx:fields>
</mx:SummaryRow>
</mx:GroupingField>
</mx:Grouping>
</mx:grouping>
</mx:GroupingCollection>
</mx:dataProvider>
<mx:columns>
<mx:AdvancedDataGridColumn resizable="false" headerText="continente" dataField="continenteCol" />
<mx:AdvancedDataGridColumn headerText="stato" dataField="statoCol" />
<mx:AdvancedDataGridColumn headerText="societa" dataField="societaCol" />
<mx:AdvancedDataGridColumn headerText="actual" dataField="actualCol" />
<mx:AdvancedDataGridColumn headerText="estimate" dataField="estimateCol" />
</mx:columns>
</mx:AdvancedDataGrid>
<mx:Button id="btnAddNew" click="goToUpdate()" icon="@Embed('icons/AddRecord.png')" toolTip="Add Record" x="10" bottom="10"/>
<mx:Button id="btnDelete" click="deleteItem()" icon="@Embed('icons/DeleteRecord.png')" toolTip="Delete Record" x="58" bottom="10"/>
<mx:Label text="Search by continente" right="300" bottom="11"/>
<mx:TextInput id="filterTxt" toolTip="Search by continente" enter="filterResults()" right="58" bottom="11"/>
<mx:Button click="filterResults()" id="filterButton" icon="@Embed('icons/SearchRecord.png')" toolTip="Search by continente" right="10" bottom="10"/>
</mx:Canvas>
<mx:Canvas id="update" >
<mx:Form id="provaForm">
<mx:FormItem label="Continente:" id="continente_form">
<mx:TextInput id="continenteCol" text=""/>
</mx:FormItem>
<mx:FormItem label="Stato:" id="stato_form">
<mx:TextInput id="statoCol" text=""/>
</mx:FormItem>
<mx:FormItem label="Societa:" id="societa_form">
<mx:TextInput id="societaCol" text=""/>
</mx:FormItem>
<mx:FormItem label="Actual:" id="actual_form">
<mx:TextInput id="actualCol" text=""/>
</mx:FormItem>
<mx:FormItem label="Estimate:" id="estimate_form">
<mx:TextInput id="estimateCol" text=""/>
</mx:FormItem>
</mx:Form>
<mx:Button label="Save" id="btnSubmit" click="insertItem()" right="81" bottom="10"/>
<mx:Button label="Cancel" id="btnCancel" click="goToView()" right="10" bottom="10"/>
</mx:Canvas>
</mx:ViewStack>
这是 .as 文件..
/** * 定义 UI 逻辑和一些数据访问代码的 ActionScript 源文件。 * 此文件使用 mx:Script 标签链接到主应用程序 MXML 文件。 * 这个文件中的大部分函数都被定义在 * MXML。 / 导入 flash.events。;
导入 mx.collections.ArrayCollection; 导入 mx.controls.AdvancedDataGrid; 导入 mx.controls.Alert; 导入 mx.controls.advancedDataGridClasses.AdvancedDataGridColumn; 导入 mx.events.*; 导入 mx.managers.CursorManager; 导入 mx.rpc.AsyncToken; 导入 mx.rpc.events.FaultEvent; 导入 mx.rpc.events.ResultEvent; 导入 mx.rpc.http.HTTPService;
//包括服务器端点URL的常量定义 包括“provaconfig.as”;
/** * 网关:这是与服务器端 php 代码的通信层 */ private var gateway:HTTPService = new HTTPService();
/** * 数组集合包含我们在网格中使用的行 */ [可绑定] public var dataArr:ArrayCollection = new ArrayCollection();
/** * 我们订购的列。每次用户点击时都会更新 * 网格列标题。 * 见 headerRelease="setOrder(event);"在 DataGrid 实例化中 * mxml 文件 */ private var orderColumn:Number;
/** * 数据库表中的字段列表 * 需要将响应解析为哈希 */ private var fields:Object = 'continente':String, 'stato':String, 'societa':String, 'actual':Number, 'estimate':Number;
/** * 当 mxml 完成加载时执行。初始化休息网关。 */ 私有函数 initApp():void
/**
* initialize the gateway
* - this will take care off server communication and simple xml protocol.
*/
gateway.url = ENDPOINT_URL;
gateway.method = "POST";
gateway.useProxy = false;
gateway.resultFormat = "e4x";
/**
* set the event handler which prevents editing of the primary key
*/
dataGrid.addEventListener(AdvancedDataGridEvent.ITEM_EDIT_BEGINNING, editCellHandler);
/**
* set the event handler which triggers the update actions - everytime an
* edit operation is finished
*/
dataGrid.addEventListener(AdvancedDataGridEvent.ITEM_EDIT_END, editCellEnd);
gateway.addEventListener(ResultEvent.RESULT, resultHandler);
gateway.addEventListener(FaultEvent.FAULT, faultHandler);
fill();
/** * 不允许编辑主键列。 * @param e DataGridEvent 包含有关网格的行和列的详细信息 * 用户点击的地方 */ 私有函数 editCellHandler(e:AdvancedDataGridEvent):void /** * 如果用户点击了主键列,则停止编辑 */ if(e.dataField == "continenteCol") e.preventDefault(); 返回;
/** * 单击“过滤器”按钮的处理程序。 * 设置另一个过滤器时,刷新集合,加载新数据 */ 私有函数 filterResults():void 充满();
/** * 用户完成编辑条目时触发的事件处理程序 * 触发“更新”服务器命令 */ 私有函数 editCellEnd(e:AdvancedDataGridEvent):void var dsRowIndex:int = e.rowIndex; var dsFieldName:String = e.dataField; var dsColumnIndex:Number = e.columnIndex;
var vo:* = dataArr[dsRowIndex];
var col:AdvancedDataGridColumn = dataGrid.columns[dsColumnIndex];
var newvalue:String = dataGrid.itemEditorInstance[col.editorDataField];
trace("a:" + dsRowIndex + ", " + dsFieldName + ", " + dsColumnIndex);
var parameters:* =
"continente": vo.continenteCol, "stato": vo.statoCol, "societa": vo.societaCol, "actual": vo.actualCol, "estimate": vo.estimateCol
parameters[dsFieldName.substr(0,dsFieldName.length-3)] = newvalue;
/**
* execute the server "update" command
*/
doRequest("Update", parameters, saveItemHandler);
/** *“更新”服务器命令的结果处理程序。 * 只是警告错误,如果没问题就什么也不做 - 数据已经 * 已在网格中更新 */ 私有函数 saveItemHandler(e:Object):void 如果(e.isError) Alert.show("错误:" + e.data.error); 别的
/** * 数据网格的 dragHeader 处理程序。当用户执行此处理程序 * 单击数据网格中的标题列 * 更新全局 orderColumn 变量,刷新 TableCollection * @param event DataGridEvent 列的详细信息 */ 私有函数 setOrder(event:AdvancedDataGridEvent):void orderColumn = event.columnIndex; var col:AdvancedDataGridColumn = dataGrid.columns[orderColumn]; col.sortDescending = !col.sortDescending;
event.preventDefault();
fill();
/** * 在“添加”状态下单击“保存”按钮的处理程序 * 收集表单中的信息并将新对象添加到集合中 / 私有函数 insertItem():void var 参数: = “方法”:“插入”,“大陆”:continenteCol.text,“stato”:statoCol.text,“societa”:societaCol.text,“实际”:actualCol.text,“估计”:estimateCol.text ;
/**
* execute the server "insert" command
*/
doRequest("Insert", parameters, insertItemHandler);
/** * 插入调用的结果处理程序。 * 如果存在错误则提示错误 * 如果调用成功,返回列表,刷新数据 */ 私有函数 insertItemHandler(e:Object):void 如果(e.isError) Alert.show("错误:" + e.data.error); 别的 去查看(); 充满();
/** *用于刷新数据的通用实用程序功能 * 获取过滤和排序,然后调度一个新的服务器调用 * */ 私有函数填充():无效 /** * 查找订单参数 */ var desc:Boolean = false; var orderField:String = '';
if(!isNaN(orderColumn))
var col:AdvancedDataGridColumn = dataGrid.columns[orderColumn];
desc = col.sortDescending;
//remove the 'Col' particle
orderField = col.dataField.substr(0,col.dataField.length-3);
dataGrid.enabled = false;
CursorManager.setBusyCursor();
var parameters:* =
"orderField": orderField,
"orderDirection": (desc) ? "DESC" : "ASC",
"filter": filterTxt.text
/**
* execute the server "select" command
*/
doRequest("FindAll", parameters, fillHandler);
/** * 填充调用的结果处理程序。 * 如果是错误,则显示给用户,否则用新数据重新填充 arraycollection * / 私有函数 fillHandler(e:Object):void 如果(e.isError) Alert.show("错误:" + e.data.error); 别的 dataArr.removeAll(); 对于每个(变量行:e.data.row 中的 XML) 变种温度: = ; for (var key: 字段中的字符串) 临时 [键 + 'Col'] = 行 [键];
dataArr.addItem(temp);
CursorManager.removeBusyCursor();
dataGrid.enabled = true;
/** * 单击列表中“删除”按钮的处理程序 * 确认动作并启动 deleteClickHandler 函数 */ 私有函数 deleteItem():void
if (dataGrid.selectedItem)
Alert.show("Are you sure you want to delete the selected record?",
"Confirm Delete", 3, this, deleteClickHandler);
/** * 确认对话框的事件处理函数在 * 删除按钮被按下。 * 如果按下的按钮为是,则删除该产品。 * @param 对象事件 * @return 什么都没有 / 私有函数 deleteClickHandler(event:CloseEvent):void if (event.detail == Alert.YES) var vo: = dataGrid.selectedItem;
var parameters:* =
"continente": vo.continenteCol
/**
* execute the server "delete" command
*/
doRequest("Delete", parameters, deleteHandler);
setTimeout( function():void
dataGrid.destroyItemEditor();
,
1);
公共函数 deleteHandler(e:*):void 如果(e.isError) Alert.show("错误:" + e.data.error); 别的 varcontine:Number = parseInt(e.data.toString(), 10); for (var index:Number = 0; index
/** * 反序列化 xml 响应 * 处理错误情况 * * @param e ResultEvent 服务器响应和有关连接的详细信息 / 公共函数反序列化(obj:, e:): var toret:Object = ;
toret.originalEvent = e;
if (obj.data.elements("error").length() > 0)
toret.isError = true;
toret.data = obj.data;
else
toret.isError = false;
toret.metadata = obj.metadata;
toret.data = obj.data;
return toret;
/** * 网关的结果处理程序 * 反序列化结果,然后调用 REAL 事件处理程序 *(在 doRequest 函数中发出请求时设置) * * @param e ResultEvent 服务器响应和有关连接的详细信息 / 公共函数 resultHandler(e:ResultEvent):void var topass: = 反序列化(e.result, e); e.token.handler.call(null, topass);
/** * 此连接的故障处理程序 * * @param e FaultEvent 错误对象 */ 公共函数故障处理程序(e:故障事件):无效 var errorMessage:String = "连接错误:" + e.fault.faultString; if (e.fault.faultDetail) errorMessage += "\n\n附加细节:" + e.fault.faultDetail; 警报.show(errorMessage);
/** * 使用网关实例向服务器发出请求 * * @param method_name String 服务器分发器中使用的方法名 * @param 参数对象名称值对用于在帖子中发送 * @param callback 调用完成时调用的函数函数 */ 公共函数doRequest(方法名:字符串,参数:对象,回调:函数):void // 将方法添加到参数列表 参数['method'] = method_name;
gateway.request = parameters;
var call:AsyncToken = gateway.send();
call.request_params = gateway.request;
call.handler = callback;
/** * 当用户单击“创建”按钮时单击处理程序 * 加载“更新”画布。 */ 公共函数 goToUpdate():void applicationScreens.selectedChild = 更新;
/** * 加载“视图”画布。 */ 公共函数 goToView():void applicationScreens.selectedChild = 视图;
私有函数 adg_itemClick(e:ListEvent):void var item:Object = AdvancedDataGrid(e.currentTarget).selectedItem; e.target.expandItem(item, !e.target.isItemOpen(item),true);
【问题讨论】:
【参考方案1】:如果我能看到整个应用程序可能会更容易回答,但如果我理解你的问题,这里是一个尝试……我不清楚异步的重点……在某种程度上,http 是异步的.但是,如果您的目标是从应用服务器/数据库推送数据,那么答案会有所不同,涉及使用 BlazeDS/LCDS 或这些技术的 OSS 克隆之一,在这些情况下,您没有使用 mx:无论如何,HttpService。这是你的意思吗?
如果没有,那么显然,您需要在 MXML 中定义一个 HttpService,并且您希望将它的结果事件绑定到一个 ActionScript 函数,该函数在服务时更改您的 dataArr (Array, ArrayCollection??)返回。如果您需要它来“轮询”您的服务以进行更改,我想您可以使用 Timer 对象或其他东西来做到这一点,但如果这是必要的,我会考虑 LCDS。
【讨论】:
我编辑添加了 .as 文件,我绝对不能在这个项目中使用 blaze、lcds 或类似文件。我只希望实际和估计字段随机变化,甚至不是全部变化,也不要一起变化。提前致谢。 这有帮助吗? cookbooks.adobe.com/… 关于你的代码的一些东西:gateway.request = parameters; var call:AsyncToken = gateway.send(); call.request_params = gateway.request; call.handler = 回调;似乎错了。我总是像链接到的 Adobe 示例那样做。【参考方案2】:我正在尝试使用与 FLEX 3 相同的内置代码。我对可以直接在创建的列表中更改数据(更改我的数据库表的内容)的方式非常着迷。 现在我尝试为某些字段合并富文本编辑器。
我正在尝试使用一个被调用的行 (selectedItem),现在我可以获取数据 - 但面临的问题是我无法编辑该字段中的文本 - (错误 1009)(有些事情是未实例化)我现在将尝试再进行一步 - 某种编辑 - 但它不是异步的。
另一个机会可能是使用 creationComplete 将所选行的数据获取到表单中,然后使用与列表相同的功能,即直接更新数据库。
我的应用程序在本地主机上运行,部署到托管服务器可能会产生一些沙盒问题?然后没有办法,只能使用 amfphp 或 ZENDamf - blazeDS
问题解决后我会回复
问候
【讨论】:
如果你能找到基于 ZENDamf 或 BlazeDS 的解决方案,它可能对我的项目非常有用以上是关于从动态 HTTPService 异步获取数据以填充 Advanced Data Grid Flex的主要内容,如果未能解决你的问题,请参考以下文章
如何在 flex 中使用相同的 Httpservice 获取更新的数据