使用 ASP.NET/Gaia AJAX/Flex 组合创建 RIA






4.38/5 (6投票s)
一个 ASP.NET 服务器控件,一个小型 Flex 库,以及一个用于将 Flex 组件集成到 ASPX 中的简单开发模式。
引言
在本文中,我想介绍 FlexContainer 项目 – 一种将 Flex 组件集成到使用 Gaiaware 开发的 ASP.NET 页面中的简单方法。
但首先,如果您不熟悉 Gaia AJAX – 一个出色的开源 AJAX 启用程序(用于 ASP.NET),我建议您访问他们的网站并阅读 Dino Esposito 的文章AJAX 的正确方式在哪里?,他在其中解释了 AJAX 的本质以及 Gaiaware 的方法。
现在,假设您想实现以下目标
- 拥有一个经典的 ASP.NET 开发模型,您倾向于坚持服务器端编程来控制演示层状态和行为,避免不必要的客户端编码或将另一个组件引入您不断增长的技术栈。
- 使用各种 Flex 组件(例如,数据可视化、图表、图像)扩展您的 ASP.NET 页面,但将它们视为常规的 ASP.NET 服务器控件。
- 让您的 Flex 组件响应 ASP.NET 事件(就像其他 ASP.NET 控件一样)以 AJAX 的方式。
- 让您的 ASP.NET 也以 AJAX 的方式响应 Flex 事件。
- 能够将您的部分或全部 Flex 组件捆绑到一个 SWF 文件中 – 从而创建一个所谓的“Flex 控件库”,从而优化页面加载/缓存。
- 完全避免使用 Flex 服务器集成解决方案,例如 WebORB 或 FluorineFX,来开发专用服务、RTMPT/RTMP 隧道、配置、许可和部署的复杂性。
换句话说,这是关于拥有一个以最直观的方式(由 Gaia AJAX 覆盖)设计的 AJAX ASP.NET 应用程序,但嵌入了 Flex 组件,并完全支持用户交互以及 .NET 和 Flex 之间的 AJAX 消息传递(由 FlexContainer 覆盖)。
FlexContainer
FlexContainer 由两部分组成 – 一个基于 Gaia 的服务器控件 (Ria.Web.Controls.dll) 和一个简单的 Flex 的 AJAX 消息传递包装器库 (FlexContainer.swc)。
在 .NET 端,FlexContainer 控件将 Flex 嵌入页面中,并作为 Flex 和 .NET 之间的通信媒介。由于它是一个 Gaia 扩展控件,因此整个客户端/服务器通信都是完全 AJAX 化的。此外,它还可以将您的消息序列化和反序列化为 JSON。
在 Flex 端,AJAX 消息传递包装器负责
- 在 .NET 发起外部调用时分派 ActionScript 事件,
- (通常响应用户操作)调用 .NET,以及
- 将 JSON 序列化/反序列化为 AS3 对象。
如果您想了解更多关于设计的信息,请访问 FlexContainer 项目页面 http://flexcontainer.googlecode.com,我在那里发布了一些文档。
代码示例和用法
ASP.NET
ASPX 页面
以下代码创建了一个 FlexContainer
服务器控件
<fc:FlexContainer
ID="fcControlTwo"
runat="server"
FlexFile="Flex/FlexControls.swf"
FlexState="controlTwo"
InitialData="Hello from .NET (InitialData)"
OnIncomingObjectEvent="fcIncomingObject"
ShowFlashMenu="false"/>
FlexState
– 用于处理 Flex 库的可选属性,其中每个 Flex 控件都有一个关联的状态。加载 SWF 时,Flex 将简单地设置指定的状态以加载控件(使用Application.currentState
)。InitialData
– 包含纯文本或 JSON 字符串的可选属性。在 Flex 控件首次在浏览器中加载时,会将其发送到 Flex 控件。可用于 Flex 控件的数据和/或状态/行为初始化。OnIncomingObjectEvent
– Flex 请求的事件处理程序。
ASPX.CS 后置代码
以下代码准备了一个用于初始化 Flex 控件的 JSON 字符串。在此,GetControlOneInitialData()
方法返回一个包含复杂 JSON 对象的字符串
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
fcControlOne.InitialData =
DemoDataServices.GetControlOneInitialData();
}
以下代码处理来自 FlexContainer
的事件。请注意,来自 Flex 的数据 e.Data
以 JsonObject
的形式传入。在此处阅读更多相关信息:https://codeproject.org.cn/KB/recipes/JSON.aspx。
protected void fcIncomingObject(object sender, FlexContainer.IncomingObjectEventArgs e)
{
if (e.Data["state"].Equals("controlOne"))
{
ajaxLabel.Text = string.Format("Name: {0} StartDate: {1} Age: {2}\n",
e.Data["name"],
e.Data["startDate"], e.Data["age"]);
}
...
}
此代码响应按钮点击事件,将 JsonObject
发送到一个 FlexContainer
fcControlTwo
。在此,GetSayHello()
返回 JsonObject
类型
protected void OnSayHelloButtonClicked(object sender, EventArgs e)
{
fcControlTwo.FlexCallObject(DemoDataServices.GetSayHello());
}
Flex
组织 Flex 控件库
以下是创建“Flex 控件库”的 MXML 片段。如您所见,每个包含的控件都有一个关联的状态名称。在 .NET 端,此名称应在 FlexContainer.FlexState
属性中指定。
<mx:states>
<mx:State name="controlOne">
<mx:AddChild>
<control:ControlOne
id="c1"
creationComplete="onControlOneComplete(event)"/>
</mx:AddChild>
</mx:State>
<mx:State name="controlTwo">
<mx:AddChild>
<control:ControlTwo
id="c2"
creationComplete="onControlTwoComplete(event)"/>
</mx:AddChild>
</mx:State>
</mx:states>
Flex 控件加载/初始化
以下代码初始化 AJAX 消息传递包装器并根据提供的 FlexState
加载控件
import flexcontainer.ajax.AjaxWrapper;
import flexcontainer.ajax.events.ExternalCallObjectEvent;
// ajax messaging/config wrapper
private var ajax:AjaxWrapper;
private function init():void {
// create ajax messaging/config wrapper
ajax = new AjaxWrapper(onAjaxCall, root.loaderInfo.parameters);
// set application current state - "load" the needed control
if(ajax.configuration.state != null)
currentState = ajax.configuration.state;
}
上述 init()
方法在 applicationComplete
时被调用。AjaxWrapper
构造函数接受两个参数:一个用于处理所有 AJAX 消息的事件处理程序(函数类型)和一个 root.loaderInfo.parameters
,用于读取特定 FlexContainer
实例的初始配置/状态。
加载 Flex 控件后,我们可能需要初始化其数据/状态/行为。示例如下
private function onControlOneComplete(event:Event):void {
// initialize grid data received from .NET
var data:Object = ajax.configuration.initialData;
c1.myLabel.text = data.someText;
c1.myDataGrid.dataProvider = new ArrayCollection(data.people);
// add event listener for item selection in grid
c1.myDataGrid.addEventListener(ListEvent.ITEM_CLICK, onGridClick);
}
请注意,ajax.configuration.initialData
提供一个 Object
类型。在此示例中,它包含用于 myLabel
初始化和 myDataGrid
的 someText:String
和 people:Array
。此外,此方法还为此控件添加了一个事件侦听器。
发送和接收消息
这是一个传入的 AJAX 消息分派器示例。ExternalCallObjectEvent
事件包含一个类型为 Object
的 data
成员(已反序列化)
// all calls from .NET are dispatched here
private function onAjaxCall(event:ExternalCallObjectEvent):void {
switch(event.data.state) {
case "controlOne":
controlOneActions(event.data);
break;
case "controlTwo":
...;
}
}
要将消息发送到 .NET,可以使用 AjaxWrapper.callToAjax()
方法。在下面的示例中,消息数据是从网格的当前选择中构建的。此调用最终会在 .NET 中得到处理,如上所示(请参阅 *ASPX.CS* 部分中的 fcIncomingObject 示例)。
// send data object to .NET on grid selection
private function onGridClick(event:ListEvent):void {
var data:Object = new Object();
data.name = event.currentTarget.selectedItem.name;
data.startDate = event.currentTarget.selectedItem.startDate;
data.age = event.currentTarget.selectedItem.age;
ajax.callToAjax(data, currentState);
}
构建/运行演示项目
从本页或项目页面下载 FlexContainer.zip,并将其解压到一个新文件夹。.\bin 文件夹包含已编译的 FlexContainer 服务器控件、AJAX 消息传递包装器 ActionScript 库和其他必需的程序集
- FlexContainer 服务器控件:.\bin\FlexContainer\Release\Ria.Web.Controls.dll
- AJAX ActionScript 库:.\bin\FlexContainer\FlexContainer.swc
- 其他程序集:.\bin\*.dll
要在本地主机上运行演示,只需使用 Visual Studio 2008 打开 .\demo\demoApplication.sln,然后按 Ctrl-F5。所有必需的程序集都已捆绑在演示文件中,并从 .\bin 文件夹引用。
源代码目前可在项目 SVN 存储库中找到。
结论
我希望一些人会发现上述方法对您的项目有用。请注意,我将在项目网站 http://flexcontainer.googlecode.com 上更新 FlexContainer。