65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.38/5 (6投票s)

2009年7月23日

GPL3

5分钟阅读

viewsIcon

33114

downloadIcon

533

一个 ASP.NET 服务器控件,一个小型 Flex 库,以及一个用于将 Flex 组件集成到 ASPX 中的简单开发模式。

引言

在本文中,我想介绍 FlexContainer 项目 – 一种将 Flex 组件集成到使用 Gaiaware 开发的 ASP.NET 页面中的简单方法。

但首先,如果您不熟悉 Gaia AJAX – 一个出色的开源 AJAX 启用程序(用于 ASP.NET),我建议您访问他们的网站并阅读 Dino Esposito 的文章AJAX 的正确方式在哪里?,他在其中解释了 AJAX 的本质以及 Gaiaware 的方法。

现在,假设您想实现以下目标

  1. 拥有一个经典的 ASP.NET 开发模型,您倾向于坚持服务器端编程来控制演示层状态和行为,避免不必要的客户端编码或将另一个组件引入您不断增长的技术栈。
  2. 使用各种 Flex 组件(例如,数据可视化、图表、图像)扩展您的 ASP.NET 页面,但将它们视为常规的 ASP.NET 服务器控件。
  3. 让您的 Flex 组件响应 ASP.NET 事件(就像其他 ASP.NET 控件一样)以 AJAX 的方式。
  4. 让您的 ASP.NET 也以 AJAX 的方式响应 Flex 事件。
  5. 能够将您的部分或全部 Flex 组件捆绑到一个 SWF 文件中 – 从而创建一个所谓的“Flex 控件库”,从而优化页面加载/缓存。
  6. 完全避免使用 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 消息传递包装器负责

  1. 在 .NET 发起外部调用时分派 ActionScript 事件,
  2. (通常响应用户操作)调用 .NET,以及
  3. 将 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.DataJsonObject 的形式传入。在此处阅读更多相关信息: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 初始化和 myDataGridsomeText:Stringpeople:Array。此外,此方法还为此控件添加了一个事件侦听器。

发送和接收消息

这是一个传入的 AJAX 消息分派器示例。ExternalCallObjectEvent 事件包含一个类型为 Objectdata 成员(已反序列化)

// 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。

© . All rights reserved.