技术开发 频道

探讨微软ASP.NET AJAX控件开发技术(客户端)


二、 控件开发客户端相关技术
    微软Ajax库的最伟大之处在于,它扩展了JavaScript的面向对象编程模型并且提供一个增强的类型系统(其中包含命名空间,类,接口,枚举,异常处理,反射及其它为.NET开发者所熟悉的结构)。
    尽管Ajax控件都是继承自Sys.UI.Control,但是,整个Ajax控件的核心却是Sys.Comoponent类。这个类模拟了.NET框架的System.ComponentModel.Comoponent类。图1展示了在Ajax控件开发中继承类之间关系的示意图。 

   
        图1.Ajax控件开发中所涉及的类关系图。
(一) Sys.IDisposable
    这个接口类似于.NET框架的IDisposable接口。组件利用的所有资源都应该在dispose方法中释放。具体地说,这些资源包括事件处理器,大型数组,等等。
(二) Sys.INotifyDisposing
这个接口允许组件用户通过disposing事件检测该组件的释放情况。
(三) Sys.INotifyPropertyChange
这个接口允许组件用户通过PropertyChanged事件检测有关属性的改变情况。在本文后面,我们还要对此展开详细的讨论。
(四) Sys.Component
该Sys.Component类要实现上面所有的接口。封装了复杂的逻辑或包含子DOM元素的组件一般都要求使用一个中央位置用于初始化和清除类的实例。这通常是通过重载Sys.Component类的initialize和dispose方法实现的。下列图2展示了Sys.Component类的主要功能。 
   
    图2—Sys.Component类主要功能展示。
  
进一步归纳来看,共存在两种类型的组件:
 Nonvisual(非可视化的)
 Visual(可视化的)
一个非可视化的组件没有任何用户接口。一个典型的例子是ASP.NETAJAX框架内置的定时器控件或一个定制的对web服务进行队列调用的组件。非可视化组件类似于ASP.NET中的ObjectDataSource和TableAdapter控件,但是没有任何用户接口。
另一方面,可视化的组件则提供了一个用户接口。一个典型的例子是Ajax Control Toolkit中的控件,UpdateProgress,以及AjaxGrid控件等等。其实,我们还可以把可视化组件进一步划分为:
 Action(Sys.UI.Action)
 Control(Sys.UI.Control)

(五) Sys.UI.Action
一个行为(Action)的目的是用来扩展一个DOM元素而不改变它的核心功能。Ajax Control Toolkit中的大多数控件就属于行为,例如该AutoCompleteTextBox,MaskEdit,DragPanel等。一个行为必须拥有一个相关联的DOM元素。注意,单个DOM元素可以拥有多个与之相关联的行为。既然本文的重点在讨论控件的开发技术,所以,我们不再进一步讨论行为的概念。如果你对此感兴趣的话,请访问Ajax Control Toolkit站点。

(六) Sys.UI.Control
    相对于上面的Action而言,一个Control(控件)本身就是一个DOM元素。创建一个控件的主要目的是通过对一个现有控件加以包装进而提供新的功能。其典型的示例就是UpdatePanel,UpdateProgress或Ajax Control Toolkit中新加入的Tab控件。下列的代码向你展示了创建一个控件所要求的最少代码。
列表1.构建一个客户端控件至少需要实现的JavaScript框架代码。
Type.registerNamespace('DummyNamespace'); DummyNamespace.DummyControl = function(element) { DummyNamespace.DummyControl.initializeBase(this, [element]); } DummyNamespace.DummyControl.prototype = { initialize : function() { DummyNamespace.DummyControl.callBaseMethod(this, 'initialize'); }, dispose : function() { DummyNamespace.DummyControl.callBaseMethod(this, 'dispose'); } } DummyNamespace.DummyControl.registerClass('DummyNamespace.DummyControl', Sys.UI.Control); if (typeof (Sys) != 'undefined') { Sys.Application.notifyScriptLoaded(); }

    上面所列出的仅是一个控件的框架代码。如你所见,与之相关联的DOM元素作为参数传入该控件的构造器函数中。我们还要重载initialize和dispose方法以便执行初始化和最后释放控件时的清理工作。因为在此列出的仅是一个虚构的控件,所以,除了调用基类的一些方法外我们什么也没有做。下列图3展示了Sys.UI.Control类提供的主要功能。 
 
 
   图3—Sys.UI.Control类提供的方法。
    一个控件和一个行为之间的另一个区别在于,一个行为允许你设置一个id而一个控件却不允许。事实上,一个控件的id与其相关联的DOM元素是一致的。下面是这个类中常用方法(有些是父类提供)的详细解释。
 get_element():返回该控件描述的DOM元素。
 get_id():返回该控件的id,为$find语句所用以引用此控件。
 set_id():如果你试图设置id,那么,你将得到一个Error.invalidOperation异常,因为控件是不允许设置id的。
 get_parent():返回父级控件。
 set_parent():设置父控件。
 get_visibilityMode():visibilityMode是一个枚举,其取值是hide或collapse。
 set_visibilityMode():设置visibilityMode的值。
 get_visibile():返回相应DOM元素的可见性。
 set_visibile():设置DOM元素风格可见性,取值为hidden或visible。
 addCssClass():把指定的CSS类添加到DOM元素的className中。
 dispose():继承自Sys.Component。
 initialize():继承自Sys.Component。
 onBubbleEvent():处理由raiseBubbleEvent激发的事件。如果这个方法返回true,则该事件将不会被上传到其父元素中进行处理。注意,如果你不处理该事件的话,你应该把此事件交由父级来作默认处理。
 raiseBubbleEvent():引发一个事件并交由父控件处理。总的来看,当你创建复杂的控件(经常是包含一个或多个子控件并且想把一个事件从子控件上交由其父控件来处理时)时往往要使用onBubbleEvent与这个方法。
 removeCssClass():从DOM元素的className中删除指定的CSS类。
 toggleCssClass():把指定的CSS类添加到DOM元素的className中(如果以前没有设置的话)。注意,如果已经指定了这个CSS类,那么,将从className中移除该类。

0
相关文章