一、简介
到目前为止,我们已经讨论了开发ajax控件所涉及的客户端相关技术。现在,让我们来讨论此过程中与服务器端相关的一些技术。
需要说明的是,在【客户端】篇中我们的举例本质上仅是使用asp.net ajax框架提供的面向对象javascript技术来增强了一个客户端图像组件,而没有明显涉及到ajax技术(除了scriptmanager在后台以ajax方式下载并管理客户端脚本代码外)。所以,这个例子是简单的,仅凭客户端相关知识就可以使用这个增强控件。
但是,在实际开发中,当要增强的客户端控件涉及到ajax技术时,或者干脆是想增强服务器端组件(如updatepanel控件)时,我们必须进行相关的服务器端编程,而这要求我们必须对ajax控件开发中所涉及的服务器端相关联的类有所了解。而且,还要以asp.net 2.0服务器控件开发相关知识为基本前提,特别是在开发复杂的ajax控件时。
在本篇中,我们要重新构造一个增强的图像按钮控件mysrvimagebutton,此控件将以asp.net 2.0服务器控件imagebutton为基础。
二、ajax控件开发服务器端相关技术
首先,让我们来看一下ajax控件开发服务器端相关组件及其关系,这些类之间的继承关系图如下图1所示。
图1:控件开发涉及的主要服务器端类之间层次结构图
上图展示了组件、控件和扩展器之间的继承关系。如你所见,为了开发一个控件(注意,component和extender不在本文讨论范围之内),我们有两个选择:其一,创建一个派生自scriptcontrol的类;其二,创建一个实现iscriptcontrol接口的类。但是,如果你想使你的控件从webcontrol派生,那么,scriptcontrol应该是一个更好的选择—因为它正是派生自webcontrol控件本身。但是,如果你想从头开发创建你的控件,并且不要求实现webcontrol所具备的任何内在特征,那么,实现iscriptcontrol则更为恰当。此外,当你想在一个现有控件(例如本文中的mysrvimagebutton)中添加ajax特征时选择使用接口iscriptcontrol也会是你的选择。但是这两种方法都要求重载下列两个方法:①、getscriptdescriptors;②、getscriptreferences。
三、getscriptdescriptors
这个方法负责在客户端以自动方式生成$create语句(而在上篇中是使用手工方式)。它使用了一个特殊类scriptdescriptor来生成它。在继续往下讨论前,首先让我们来浏览一下scriptdescriptor类中的继承层次图(如图2所示):
图2:scriptdescriptor类中的继承层次图
显然,每一种具体类型的组件都存在其单独的描述符。如果你在开发一个常规组件,那么,这个方法会返回一个scriptcomponentdescriptor的实例。对于扩展器而言,该方法返回的是一个scriptbehaviordescriptor实例;而对于一个控件,则返回scriptcontroldescriptor类的实例。该描述符中提供了一些特定的方法用于创建服务器端与客户端的“连接”。下面,还是让我们来分析一个有关$create语句是如何在服务器端“注入”的简短示例:
//上篇中从客户端以手工方式使用$create
$create(ajaximagebuttonnamespace.mycliimagebutton,
{'hoverimageurl':'images/updateh.gif'},
{'click':buttonclicked}, null, $get('clibtn'));
在本文中,我们在服务器端以下列几个语句共同自动生成$create语句:
scriptcontroldescriptor desc =
new scriptcontroldescriptor("ajaximagebuttonlib.mysrvimagebutton",
clientid);
if (!string.isnullorempty(hoverimageurl))
{
desc.addproperty("hoverimageurl", hoverimageurl);
}
if (!string.isnullorempty(clientclickfunction))
{
desc.addevent("click", clientclickfunction);
}
return desc;
在上面的代码中,我们在构造器中传递客户端类型(尽管客户端和服务器端具有相同的类型名)和dom元素id。这一步将填充$create语句的第一个和最后一个参数。此后,我们设置hoverimageurl属性,它对应于$create语句的属性部分。最后,通过设置click事件处理器,我们填充$create语句的事件部分。下面是脚本描述符中暴露的几个重要的方法:
1)addproperty()
这个方法能够在客户端添加一个属性。第一个参数相应于属性名,第二个参数对应该参数的取值。
2)addevent()
这个方法在客户端添加一个事件。第一个参数相应于事件名,第二个参数对应你想绑定的函数的名称。
3)addscriptproperty()
这个方法能够把javascript代码指定为属性的一个值。对于复杂的属性赋值通常都要求这样的操作。
4)addelementproperty()
这个方法在客户端添加一个属性,但是其与addproperty方法间的区别在于,该值作为一个参数传递给$get方法。
5)addcomponentproperty()
这个方法负责在$create语句的component部分添加一个组件引用。该值将被用于$find语句中实现属性的赋值。这个方法的第一个参数相应于属性名,第二个参数对应该组件的id。
四、getscriptreferences
这个方法负责在scriptmanager中注册javascript文件。在这个方法中,针对每一个要求的javascript文件,我们都需要创建一个相应的scriptreference实例。例如,在图像按钮例子中,我们按如下方式注册javascript文件:
ienumerable<scriptreference> iscriptcontrol.getscriptreferences()
{
return new scriptreference(page.resolveurl("~/srvimagebutton.js"));
}
此外,我们还可以以嵌入式资源方式注册javascript文件。为此,我们必须首先在visual studio的解决方案资源管理器中把一个javascript文件标记为一种嵌入式资源。然后,我们必须添加上webresource属性以便利用asp.net 2.0 web资源处理器。下列代码展示了如何把一个javascript文件注册为一个嵌入式资源: