现在,让我们看一个正在构建的该控件的用法示例,它的用法可能如下情形: <check">

用AJAX开发智能Web应用程序之高级篇(2)

80酷酷网    80kuku.com

  ajax|web|程序|高级•标准HTML复选框不支持"校验"事件以允许取消一个GUI行为,而这种要求可能存在于某些应用程序中

现在,让我们看一个正在构建的该控件的用法示例,它的用法可能如下情形:

<checkbox id="cbx_1" value="N" labelonleft="true"

label="Show Details:" onValue="Y" offValue="N"/>

另外,我们的控件将支持可取消的事件onItemChanging和通知事件onItemChanged

定义定制标签

从结构上讲,一个定制标签是一个具有一个HTC扩展名的文件-它在<PUBLIC:COMPONENT>和</PUBLIC:COMPONENT>标志之间对它的属性,方法和事件加以描述

为了定义一个定制CHECKBOX标签,我们创建一个如下列代码片断中的文件checkbox.htc-其中,第一行负责设置该组件的标签名:

<PUBLIC:COMPONENT NAME="cbx" tagName="CHECKBOX">

<PROPERTY NAME="value" GET="getValue" PUT="putValue" />

//我们把组件的所有另外的属性放在这里

<METHOD NAME="show" />

//我们把组件的所有另外的方法放在这里

<EVENT NAME="onItemChanging" ID="onItemChanging"/>

//我们把组件将向应用程序激活的所有另外的事件放在这里

<ATTACH EVENT="oncontentready" HANDLER="constructor" />

//我们把组件自己处理的另外的事件放在这里

<SCRIPT>

//我们把所有的方法,属性getters和setters和事件处理器放在这里

</SCRIPT>

</PUBLIC:COMPONENT>

使用定制标签

尽管HTC文件的内容比较重要,但是这与其文件名是什么无关值得注意的是,指向该HTC文件的URL需要被使用IMPORT指令指定-这必须在相应的定制标签第一次出现之前(在页面上)完成下面是最简单的可能的页面使用一个定制的复选框可能看上去的样子-假定该页面和HTC文件处理同一个文件夹下:

<HTML xmlns:myns>

<?IMPORT namespace="myns" implementation="checkbox.htc" >

<BODY>

<myns:checkbox id='cbx_1' label='Hello'/>

</BODY>

</HTML>

请注意,定制CHECKBOX是怎样在打开的HTML标签中被映射到一个非缺省的命名空间"myns"的这个IMPORT指令实现把HTC同步加载到浏览器的内存并且还指示浏览器怎样为适当的命名空间实现名称确定的(HTC到命名空间的关联可能是多对一的)

定制标签的构造器

最好的初始化HTC的方法是,一旦它被装载就处理oncontentready事件因此,我们可以定义处理器函数-为了概念清晰起见,我们称之为构造器:

<ATTACH EVENT="oncontentready" HANDLER="constructor" />

constructor()的逻辑是简单的:根据属性labelonleft的值(见下面的属性定义)按顺序连接一个常规HTML复选框和HTML标签:

function constructor() {

 //我们将把一个HTML复选框和标签添加到元素体

 //详细情形见列表2

}

定义定制标签属性

为了定义属性labelonleft,我们又在<PUBLIC:COMPONENT>部分加上一行:

<PROPERTY NAME="labelonleft" VALUE="true"/>

请注意,这个属性并没有包含getter和/或setter方法属性onValue和offValue不仅提供了从复选框状态到一个商业值域的映射而且不需要getters和setters:

<PROPERTY NAME="onValue" VALUE="true"/>

<PROPERTY NAME="offValue" VALUE="false" />

然而,属性checked是用两个getter和setter定义的:

<PROPERTY NAME="checked" GET="getChecked" PUT="putChecked" />

因此,我们在<SCRIPT>部分建立了上面两个方法的定义正如你所见,setter putChecked()-将在每次复选框状态改变时激发-把value属性设置为下面两个变体之一:onValue或OffValue请注意,putChecked()将不仅可由在复选框-宿主页面中的脚本触发,而且也能通过在checkbox.htc中的相应的任何赋值操作触发

var _value;

function putChecked( newValue ) {

 value = (newValue?onValue:offValue);

}

function getChecked(){

 return ( _value == onValue);

}

六、为定制标签定义事件

让我们看一下onItemChanging和onItemChanged事件的定义以及这些事件是怎样在value属性的setter内部被激发和处理的(见所附源码中的列表2)方法putValue()有几个让人感兴趣的地方首先,在分析CHECKBOX标签期间,可以调用这个方法-只要指定这个HTMLvalue属性正解释了为什么我们为非构造对象建立一个单独的逻辑分支-为把构造过程与一个对用户击键的反应区别开来其次,在此我们展示了定制事件onItemChanging的创建和处理-它允许应用程序取消行为请注意,通过这种方式,无论是击键还是通过方式实现赋值都能达到取消的目的

事件取消

为了取消事件,一个应用程序应该拦截该事件并且把event.returnValue设置为false下面的代码片断展示了应用程序是怎样实现取消事件过程的:

cbx_1::onItemChanging() {

. . . . .

if (canNotBeAllowed) {

 event.returnValue=false;

 . . . . .

}

如果事件没被取消,putValue()把内部的普通HTML复选框的checked属性设置为每个相应的当前值-如果它等于onValue,这个内部复选框将被选中;如果它等于offValue(不存在第三种选择),复选框不被选中(完整的列表见本文所附源码中的列表2)

复选框的HTML内幕

我们控件的绘制是通过助理函数addLabel()和addCheckBox()来实现的并且从一个constructor()内部调用这些函数把HTML注入进元素的innerHTML这种注入式HTML的一种简化形式如下所示:

<LABEL for=cb_{uniqueID}>Show Details:</LABEL>

<INPUT id=cb_{uniqueID} type=checkbox />

在此,uniqueID是一个由IE所生成的唯一的(在一个页面内)字符串-它用来识别HTC的实例

七、 再封装

在我们的CHECKBOX中有一个缺点按照我们建立它的方式,在constructor()期间被注入的HTML将隶属于宿主该HTC的页面的DOM而且,全局的JavaScript变量like_value属于它们所在的文档的全局范围这是危险的,因为我们偶然会遇到命名冲突的可能性:最明显的情形是使用同一个组件的多个实例另外这还会导致一个可能性-我们的控件可能会偶然地用相同的名称参考其它对象,反之也如此

为简化起见,需要建立一种专门的机制来为对象授权启动一个真正模块化方法幸好,HTC技术支持一种智能答案-viewLink

把一个控件声明为封装的最容易的方法是把一个额外声明放到打开和关闭的PUBLIC:COMPONENT标签之间:

<PUBLIC:DEFAULTS viewLinkContent/>

该控件立即就变成封装性的;而且它有自己的HTML文档树-成为主文档的原子组件该对象的每个实例有它自己的实例值的集合并且只有公共方法和属性能够从外界代码中加以存取换句话说,该viewLink机制充分地启动了复杂的Web应用程序的设计和实现-通过使用一种真正的OO的基于组件的方法

特别地,我们可以简化代码-通过从内部复选框和HTML标签的定义中删除uniqueID后缀,因为我们不再担心命名冲突因此,我们可以替换下面这一行:

eval( 'cb_'+uniqueID).checked = ( _value == onValue );


cb.checked = ( _value == onValue );

并相应地改变addCheckbox()和addLabel()

八、 结论

既然AJAX竞赛刚刚开始,那么就不存在什么AJAX标准并且没有现成的你可以依赖以构建你的应用程序的可广为接受的RAD工具虽然软件供应商们可能还需要较长一段时间来创建这种强健的开发平台,AJAX热心者已经开始着手准备-通过一些良好定义的API把可重用的代码块封装为商业组件

以这种方向导航,本文概括了AJAX语言的OO"力量"-JavaScript另外,还展示了一种可用的组件-授权策略-客户端定制标签技术我们在仅描述IE特定的定制标签的同时,还另外提供了一个可下载的实例-适于Mozilla浏览器的可扩展的绑定实例



分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间
点击: