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

使用客户端回调(AJAX 风格)提供上下文相关帮助

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.62/5 (8投票s)

2006 年 9 月 22 日

8分钟阅读

viewsIcon

40476

downloadIcon

237

本文主要介绍如何使用 .NET 2.0 中的客户端回调(AJAX 风格)在网页中提供上下文相关帮助。

Sample Image - ContextSensitiveHelp

引言

本文主要介绍如何使用 .NET 2.0 中的脚本回调(AJAX 风格)在网页中提供上下文相关帮助。

简要场景

当我们填写在线表单或尝试输入各种字段的搜索/过滤条件时,我们可能都曾希望能够获得关于我们应该做什么的简要说明或帮助。按需提供此类信息肯定会使用户更加舒适。

本文介绍的上下文相关帮助就是如何实现这一点的。

以下一系列步骤简要描述了场景

  • 您正在尝试填写一个网站上的表单。
  • 您看到一个屏幕元素/表单字段需要输入值。
  • 您感到困惑或迷茫。
  • 将鼠标移到元素名称上。
  • 光标符号揭示了您的表情。光标旁边显示一个问号。
  • 点击它。
  • 动态地,帮助会出现,即与点击的屏幕元素相关的帮助/说明。

问题

如何动态获取帮助文本?

我见过的解决方案

解决方案 1

我见过一些网站会在用户点击某个元素时刷新或回发页面,以便在预定义的分离区域中提供说明或帮助文本。这绝对是一种重量级的方法。考虑一个只包含 10 个词的帮助文本。我们为了获取几字节的数据而发送了几千字节的数据。

解决方案 2

我见过的另一个解决方案是在加载页面时加载所有屏幕元素的帮助文本,并将其存储在客户端的 JavaScript 数组中。在每个屏幕元素的点击事件上,会调用 JavaScript 来从数组中获取帮助文本,并将当前的屏幕元素索引作为参数传递。对于只有少数屏幕元素的页面来说,这似乎还可以,但缺点在于屏幕元素多达数百个的网页。我见过一个应用程序有一个页面有 104 个字段,而每个字段的帮助文本不少于 4 行,每行 15 个词。所以,想象一下与页面一起加载的帮助文本的大小。这绝对是一项非常繁重的工作!搜索“上下文相关帮助”会给你很多其他解决方案,但它们大同小异。

本文提供的解决方案

当用户点击屏幕元素以获取帮助时,会使用 .NET 的客户端回调功能向服务器发起异步调用,从服务器上的 XML 文件检索所需的帮助文本,并将其返回给客户端。服务器会有一次往返,但**整个页面不会回发**,也不会有闪烁。

幕后

当我们在地址栏输入 URL 并按 Enter 键时,浏览器会执行一个 HTTP 命令,打开与指定 IP 地址的套接字,发送数据包,并等待响应。浏览器会显示响应。页面回发时也会重复相同的过程。在这种情况下,页面输出会明显重新显示。现在我们不想将整个页面回发到服务器并刷新整个页面。我们只想动态显示/更改/更新其中的一部分,从服务器获取数据而不引起任何闪烁。所以,这里有两个挑战。

  • 与所需 IP 地址建立 HTTP 连接以获取数据。
  • 动态刷新页面。

第一个任务由 .NET 2.0 脚本回调处理,第二个任务由 DHTML 处理。

所以,我们所要做的就是

  • 网页应继承 ICallbackEventHandler
  • 获取回调事件引用并注册客户端脚本块。
  • 实现 ICallbackEventHandlerRaiseCallbackEvent 方法。

要使用 ASP.NET 2.0 脚本回调,您需要实现 ICallbackEventHandler 接口。本文后面将讨论原因。页面的触发元素,即页面中触发某个事件并需要从服务器获取数据的元素,需要绑定到一些 JavaScript 代码,该代码会从当前页面检索输入数据并调用系统提供的脚本函数。此函数会打开到相应远程 ASP.NET 页面的 HTTP 连接。ASP.NET 运行时会检测到回调调用,并检查页面是否实现了 ICallbackEventHandler。如果实现了,运行时会在页面上执行 RaiseCallbackEvent 方法。服务器端方法的返回值将作为对先前请求的响应传递回客户端。在客户端,响应会传递给一个用户定义的 JavaScript 回调函数,该函数可以通过 DHTML 更新用户界面。正如所见,会发生往返,但整个页面不会回发。好的地方在于,用户可以在请求并行处理时继续使用页面中的控件。

将所有内容放在一段话里就像一次吞下一块披萨。让我们把披萨分成小块,享受它的味道。

代码演练

上述过程通过以下代码片段进行解释

页面继承 ICallbackEventHandler 接口

public partial class _Default : PageManager, ICallbackEventHandler
{
    ………………………
    …………………..
    …………………..
}

获取对系统提供的脚本的引用

strHelpReference = Page.ClientScript.GetCallbackEventReference(this,
                                                              "arg",
                                           "JavaScriptCallBackHelp",
                                                          "context"
                                                                  );

注册此客户端脚本块

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), 
                      "CallBackHelp", strHelpScript, true);

此 JavaScript 方法绑定到页面上的某个事件。例如,页面上标签/文本“title:”的点击事件与 GetContextSensitiveHelp JavaScript 方法相关联,该方法触发 CallBackHelp JavaScript 方法。如上所示,它持有用于回调的系统生成脚本方法的引用。在服务器端处理完成后,将触发 JavaScriptCallBackHelp JavaScript 方法,并将服务器端方法返回的结果作为参数传递。

用于检索与被点击元素相关联的帮助文本的代码写在 RaiseCallbackEvent 中。

public void RaiseCallbackEvent(string strEventArgument)
{
    try
    {
        char[] charSeperator = { '#' };

        //If the aruguement starts with help, it indicates 

        //that the call back event occured 

        //for providing Context Sensitive 

        //help for the selected screen element.

 
        if (strEventArgument.StartsWith("Help"))
        {
            strCallBackResult = LoadContextHelp(strEventArgument.Remove(0, 4));
        }
    }
    catch (Exception ex)
    {
        Response.Write(ex.ToString());
    }

}

LoadContextHelp 方法是实际获取与屏幕元素相关联的帮助文本的方法。在附加的代码中,我从 XML 文件中获取帮助文本。您可以根据自己的意愿以任何其他方式实现此方法。

结果被赋给字符串变量 strCallBackResult,该变量由 GetCallbackResult 方法返回。RaiseCallbackEventGetCallbackResult 方法的触发由运行时完成。

附加应用程序中其他组件的概述

创建了一个用户控件 HelpControl 来包含帮助部分的标记。

创建了一个独立的类 XmlMessages。它包含 XML 文件的路径,整个 XML 上下文是一个 XmlDocument 对象,该对象作为 XmlMessages 类的属性暴露。提供了各种方法来使用 Xpath 从 XML 文件中获取所需的节点/节点。

创建了一个独立的类 CacheManager 来提供加载和刷新缓存数据的方法。

一个独立的 PageManager 类需要被应用程序中的所有网页继承。在该类的 Init 方法中,会触发 CacheManager 方法以从缓存加载数据或刷新缓存中的数据。

有关使用的 JavaScript 函数的详细信息

帮助文本的标题和描述通过字符“#”连接在同一个参数中返回。JavaScript 回调方法 JavaScriptCallBackHelp 将返回的结果分割成标题和描述,并触发 helpfunctions.js JavaScript 文件中的 ShowHelp JavaScript 函数。

function JavaScriptCallBackHelp(help, context)
{
    var helpArray = new Array();
    helpArray = help.split('#');
    ShowHelp('objHelpControl',helpArray[0],helpArray[1]);
}

JavaScript 函数 ShowHelp 设置与标题和描述相关的 div,并更改容器 div 的样式为 block 以显示帮助。

function ShowHelp( strPrefix, strTitle, strMessage ) 
{    
    var objContainer = document.getElementById(strPrefix + '_csh_container');
    var objTitle = document.getElementById(strPrefix + '_csh_Title');
    var objHelp = document.getElementById(strPrefix +  '_csh_Description');
    
    objContainer.style.display = 'block';
    objTitle.innerHTML = strTitle;    
    objHelp.innerHTML = strMessage;    
}

当点击关闭图像时,会触发 SetHelpClosed 函数来关闭帮助部分。这是通过将容器 div 的显示样式更改为 none 来实现的。

function SetHelpClosed(objElement) {
    /* get the container object */
    objParentObject = objElement.parentElement;        
    while (objParentObject.id=="" && objParentObject != null)
        objParentObject = objParentObject.parentElement;        
    
    if (objParentObject == null) return false;
    
    objParentObject.style.display="none";       
}

还有一些其他的 JavaScript 函数用于制作可拖动的帮助部分。这些函数的详细信息不属于本文的讨论范围。

关注点

在附加的代码中,除了脚本回调之外,您还可以观察到各种概念的实际应用,例如

  • 基类实现
  • 缓存
  • 主题(对控件使用皮肤文件)
  • 使用 XmlDocument 对象和 Xpath
  • 用户控件

结论

上下文相关帮助功能可能不适用于所有网页。此功能应根据网页的类型和网页中使用的术语来提供。例如,在某些特定于业务的内联网网站(如保险)中,一个网页上会有数百个元素,实现此功能会非常合适。无论如何,实现此功能不应基于屏幕字段的数量。即使只有几个字段,如果需要,是的,绝对要提供。

© . All rights reserved.