四、在Web页面中应用非可视化组件
为了在一个ASP.NET AJAX应用程序页面中使用前面创建的定制客户端组件,你需要下列步骤:
◆在Web页面中注册该组件的脚本库。
◆创建一个组件实例。
下面我们来详细讨论这些步骤。
(一)在Web页面中注册组件的脚本库
我们可以通过声明方式或编程方法通过一个ScriptManager控件来注册在页面中使用一个客户端控件所需要的脚本。
【注意】客户端组件可以受托管于一个实现了IScriptControl接口的定制服务器控件。这样的一个定制服务器控件可以自动地注册要求的组件脚本并且暴露设置组件属性和事件绑定的声明性标记。这样将使得页面开发者更容易使用此客户端组件。
下面的示例展示了一个注册组件脚本的ScriptManager控件的声明性标记:
在此,元素的结点下包含了一个元素。结点的path属性参考定义一个组件类的DemoTimer.js文件的路径。
【特别注意】所有要使用ScriptManager控件进行注册的脚本文件都必须调用notifyScriptLoaded方法以通知应用程序该脚本已经加载完毕。大多数情况下,嵌入式于一个程序集内的脚本不应该调用这个方法。
(二)创建定制组件实例
你可以通过调用Sys.Component.create方法(或$create快捷方式)来实例化一个客户端组件。为此,你需要把相应的参数传递到$create方法以指定该组件的类型。你还要传递一个JSON对象,这个JSON对象用于包含一个要求的ID值以及可选的初始属性值和事件处理器绑定。
下面这个示例展示了如何通过调用$create方法来实例化一个组件实例。
function pageLoad() { $create(Demo.Timer, {enabled:true,id:"demoTimer1", interval:2000}, {tick:OnTick}, null); }
|
五、打造定制的Demo.Timer组件
从现在开始,我们来创建一个名字为Demo.Timer的定制客户端组件,然后把它应用于一个Web页面中。这里的Demo.Timer是一个简单的定时器组件,它能够根据interval属性激发一个propertyChanged事件,并暴露一个enabled属性,还定义了一个tick事件。使用这个Demo.Timer组件的页面开发者可以绑定到propertyChanged事件并且在每次更新interval属性时采取自己的行动。当然,开发者还可以处理tick事件。
为了创建该Demo.Timer组件的代码,我们需要:
1.在ASP.NET AJAX应用程序的目录下创建一个名字为DemoTimer.js的文件。
2.然后,把下列JavaScript代码添加到该文件中:
Type.registerNamespace("Demo"); Demo.Timer = function() { Demo.Timer.initializeBase(this); this._interval = 1000; this._enabled = false; this._timer = null; } Demo.Timer.prototype = { //声明该prototype中的值类型 get_interval: function() { /// 以毫秒为单位的时间间隔值 return this._interval; }, set_interval: function(value) { if (this._interval !== value) { this._interval = value; this.raisePropertyChanged('interval'); if (!this.get_isUpdating() && (this._timer !== null)) { this._restartTimer(); } } }, get_enabled: function() { /// 当启动定时器时为True;否则为false。 return this._enabled; }, set_enabled: function(value) { if (value !== this.get_enabled()) { this._enabled = value; this.raisePropertyChanged('enabled'); if (!this.get_isUpdating()) { if (value) { this._startTimer(); } else { this._stopTimer(); } } } }, //事件 add_tick: function(handler) { /// 增加一个相应于tick事件的事件处理器 /// 添加事件的处理器 this.get_events().addHandler("tick", handler); }, remove_tick: function(handler) { /// 删除tick事件的一个事件处理器 /// 删除事件的处理器 this.get_events().removeHandler("tick", handler); }, dispose: function() { //调用set_enabled以便激发属性改变事件 this.set_enabled(false); //保证的确停止了,这样在释放后就不必调用了 this._stopTimer(); //确保调用base.dispose() Demo.Timer.callBaseMethod(this, 'dispose'); }, updated: function() { Demo.Timer.callBaseMethod(this, 'updated'); //在批更新(this.beginUpdate(), this.endUpdate())后调用 if (this._enabled) { this._restartTimer(); } }, _timerCallback: function() { var handler = this.get_events().getHandler("tick"); if (handler) { handler(this, Sys.EventArgs.Empty); } }, _restartTimer: function() { this._stopTimer(); this._startTimer(); }, _startTimer: function() { //保存定时器cookie便于以后删除之用 this._timer = window.setInterval(Function.createDelegate(this, this._timerCallback), this._interval); }, _stopTimer: function() { if(this._timer) { window.clearInterval(this._timer); this._timer = null; } } } //描述这个组件所有的属性、事件和方法的JSON对象。 //注意,此组件应该能够通过Sys.TypeDescriptor方法和通过xml-script进行寻址。 Demo.Timer.descriptor = { properties: [ {name: 'interval', type: Number}, {name: 'enabled', type: Boolean} ], events: [ {name: 'tick'} ] } Demo.Timer.registerClass('Demo.Timer', Sys.Component); //既然这个脚本不是通过System.Web.Handlers.ScriptResourceHandler //加载的,所以,我们在此调用 // Sys.Application.notifyScriptLoaded来通知ScriptManager。 //这是脚本的结束处,根据前面的揭示,这一句必须有 if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
|
【注】上面的JavaScript脚本集中体现了ASP.NET AJAX 1.0框架对于客户端JavaScript编程进行的简化。很显然,这里仍然基于JavaScript脚本语言中的prototype模型,但已对之进行了面向对象的进一步包装。
【文章相关内容】
第一页:非可视化客户端组件的基本功能
第二页:实现一个派生自Component的客户端组件
第三页:在Web页面中应用组件