多数在表示层应用的服务器控件主要由两个部分组成服务器端功能和客户端功能服务器端功能永远是服务器控件的核心而随着技术的发展客户端功能也逐渐变得越来越重要只有两个部分互相配合才能创建出功能强大界面丰富的服务器控件本文将讨论在服务器控件中实现客户端功能的相关问题具体内容包括客户端功能概述实现简单客户端功能实现复杂客户端功能以及部署客户端文件的实现方法等内容
客户端功能简介
在Web编程中客户端功能传统上是由Web页开发人员负责并且不被封装在服务器组件中脱离了这一范畴并使服务器控件能够发出客户端脚本从而使服务器控件能够将客户端处理与服务器端处理结合起来实现客户端功能对于提高服务器控件的交互性和可扩展性的意义重大例如常见的TreeViewTabStripToolBar控件等这些优秀的服务器控件具有很强的交互性和丰富的用户界面而这些特征的实现与客户端功能是密不可分的
实现客户端功能的技术主要是客户端脚本(JavaScriptVBScript等)和DHTML因此作为一名合格的开发人员必须具有熟练应用这些技术的能力除此之外还要掌握将客户端功能与服务器控件密切结合的方法这些内容包括实现简单客户端功能实现复杂客户端功能部署客户端脚本文件的方法
实现简单客户端功能
如果自定义服务器控件的客户端功能比较简单例如仅仅是弹出窗口或者改变背景颜色等那么对于这种情况通过不使用单独的客户端脚本文件封装而是直接在控件呈现中实现其实现的关键是在控件的Attributes中添加适当的客户端处理程序以下实例说明从SystemWebUIWebControlsButton类派生的控件MyClickButton它为客户端单击事件提供事件处理程序请看下面的代码
public class MyClickButton : Button{
//相关代码
protected override void AddAttributesToRender(HtmlTextWriter writer) {
baseAddAttributesToRender(writer);
writerAddAttribute(onclick nfirm(谢谢您! ););
}
}
如果读者已经阅读了前面有关控件呈现的文章那么很容易理解以上代码以上代码重写了AddAttributesToRender方法它为MyClickButton控件定义了一个名为onclick的Attribute其值指示在客户端弹出一个包含自定义信息的确认窗口如果读者所开发的服务器控件的客户端功能都比较简单那么可以尝试利用重写AddAttributesToRender的方法予以实现
下面是为使用MyClickControl控件而创建的ASPX页面源代码
<%@ Page Language = C# %>
<%@ ReGISter TagPrefix=Custom Namespace=MyControls Assembly = MyControls %>
<html>
<body>
<form runat=server>
请点击下面的按钮
<Custom:MyClickButton Id = demo runat=server/>
<br>
</form>
</body>
</html>
当用户点击MyClickControl控件时立刻弹出一个包含提示信息的确认窗口需要注意的是弹出确认窗口并不是由于页面回传而是用户激发客户端处理程序的结果当点击确定按钮之后才会发生页面回传
实现复杂客户端功能
如果客户端功能比较复杂这时一般将完成其功能的代码封装在客户端脚本文件中为了将这些脚本文件与服务器控件紧密结合起来 框架提供了将客户端脚本文件加入服务器控件所需的必要方法这些方法基本都包含在ClientScriptManager类中开发人员可以通过调用Page类的ClientScript属性来获取ClientScriptManager类实例该类用于管理脚本注册脚本和向页添加脚本
可能读者对于ClientScriptManager类有些陌生它是ASPNET 的新增类该类是专门用于替代已经停止使用的用于管理脚本的Page类的部分方法而创建的例如在ASPNET x中曾经出现的ReGISterClientScriptBlockRegisterStartupScript等等这些方法都已经停止使用而改用ClientScriptManager类的相关方法来实现
下面列举了来自ClientScriptManager类的与实现复杂客户端功能有关的几个常用方法
()RegisterClientScriptBlock方法
向页的顶部添加一个脚本块以字符串形式创建脚本然后将其传递给方法方法再将脚本添加到页中可以使用此方法将任何脚本插入到页中请注意脚本可能在所有元素完成之前呈现到页中因此您可能无法从脚本中引用页上的所有元素
()RegisterClientScriptInclude方法
与 RegisterClientScriptBlock 方法类似但此方法将添加引用外部 js 文件的脚本块包含文件在任何其他动态添加的脚本之前添加因此您可能无法引用页上的某些元素
()RegisterStartupScript方法
向页中添加一个脚本块该脚本块在页完成加载后引发页的 onload 事件之前执行该脚本通常不创建为事件处理程序或函数它通常只包含要执行一次的语句
()RegisterOnSubmitStatement方法
添加响应页的 onsubmit 事件而执行的脚本该脚本在提交页之前执行允许您取消提交
()IsStartupScriptRegistered方法
确定Page对象是否注册了启动脚本
()IsClientScriptBlockRegistered方法
确定Page对象是否注册了客户端脚本
除了以上几个方法之外ClientScriptManager类还包括其他一些相关方法有兴趣的读者可以阅读相关资料通过在服务器控件中灵活使用以上方法我们可完成为控件加入客户端行为同时也带来了以下好处
()有效的减少所显示页面的大小因为很多有关客户端功能的代码都封装到了客户端脚本文件中在控件中只需引用脚本文件的地址即可
()由于同一控件共享脚本文件因此通过浏览器的缓存机制可以改善应用程序的性能
()提高了控件的灵活性和可扩展性通过修改脚本文件控件开发者可以很容易的修改客户端功能而不用编译服务器控件
另外在对复杂客户端功能处理的过程中有时还需要在客户端脚本中访问控件控件开发者可以在脚本中访问呈现到客户端的对象并且对其进行操作下面来简单介绍一些有关内容
Control基类有一个ClientID的属性它作为所呈现的元素的ID属性呈现ASPNET动态为一个控件生成ClientID并且确保页上每一控件的ClientID是唯一的因此可通过在文档对象模型中使用控件的ID在客户端上访问该控件(即由该控件呈现的元素)控件还可以使用ClientID为它可以呈现的任何附加元素(例如隐藏域)生成唯一名称
将ClientID的值发出到内联脚本中(或者发出到脚本库的代码中)可能是较为棘手的因为该ClientID必须插在字符串变量中的正确位置以下实例使用转义符将ClientID插入构成内联脚本的字符串中
string element = documentgetElementById(\ + ClientID + \);
PageRegisterArrayDeclaration(Page_Validators element);
另外还可以使用String类的重载的Format方法撰写使用ClientID的客户端脚本
部署客户端文件的方法
默认安装的情况下在wwwroot文件夹下存在一个子文件夹asp_client其中保存了用于支持智能导航验证控件等功能的客户端脚本文件很显然这些文件非常重要为了提高应用的规范性建议开发人员在部署客户端文件过程中采用以下方法
· 将包含有客户端脚本的文件夹置于asp_client文件夹中尤其是对于那些安装在全局配件缓存(GAC)中的控件更应该这样做
· 包含脚本的文件夹推荐使用与控件相关的名称
· 推荐在包含脚本的文件夹下不要直接放置脚本文件而是再创建一个名称为控件版本号的文件夹将脚本文件放置其中
例如开发人员创建了一个版本为的服务器控件MyControl其关联一个客户端脚本ClientScriptjs并且将该控件加入了GAC中这时推荐部署客户端脚本文件的路径为c:\Inetput\wwwroot\asp_client\MyControl_Client\\ClientScriptjs另外在客户端文件库中存储的并不仅是脚本文件也可以加入控件所需的样式表文件图片等其他文件
以上为部署客户端文件的推荐方法那么这是不是说明所有的客户端脚本文件都需要遵循以上规则呢?当然不是只要开发人员从实际出发从提高程序的可维护性和方便性着眼那么无论客户端脚本文件置于何处都是可以的
小结
本文主要介绍了与实现服务器控件客户端功能相关的内容这些内容对于开发出交互性强的服务器控件非常重要掌握这些内容并不困难真正困难的是如何开发完成客户端功能的CSS文件JS脚本DHTML程序等这些技术的掌握不是一朝一夕就可以完成的它需要扎实的基础刻苦的钻研而所有这些技术和精神品质都是一名合格的开发人员所必需掌握的精髓缺一不可