高级组件的功能已经根据客户反馈,性能等诸多因素进行了修改。就以之前的Button为例,DomEvent类使用了一个基于标准的法提供了一套API用于DOM事件的分发。这个抽象能够良好运行在多个浏览器中。
许多API已经从CTP版本原来的地方(大都是Control类的成员)转移到了RTM版本中新的地方,而且被定义成了静态函数。这种做法减少了Contorl类的体积,而且这些操作DOM元素的API也能被开发人员随意使用了,不必像以前一样必须初始化一个Control对象。下面的示例展示了使用DomElement类的方式:
Sys.UI.DomElement.addCssClass($get('AddressLine1'), 'rqdFieldStyle');
请注意,在这里使用了新的$get函数,后面将对这些简写函数进行解释。
Component,Control and Behavior Class
在CTP版本中存在着以下三个类: Component, Control和 Behavior。它们提供了许多重要的功能。其中 Control和 Behavior都是 Component的子类。
这个模型在RTM版本中依旧存在。然而,经过了我们对它们用法的研究,并联系设计的原始目的进行研究后,改变了它们的使用方法。例如,在CTP版本中,一个 Control类和一个DOM元素紧密联系了起来,您能通过 Control对象来访问这个DOM元素。但是,尽管 Behavior和DOM元素有直接的关系,我们却只能通过 Control实例的一个Collection类型属性来访问到它。
RTM版本使DOM元素相关的工作变得更加灵活。 Control和 Behavior在概念上非常相似,都和一个DOM元素有这密切的关系。然而,现在它们已经相互独立了。
在RTM版本中,您能将一个 Control实例与一个DOM元素联系起来,并且可以通过control来获得,这一点和CTP版本相同。另外,如果一个 Behavior有一个 Name属性,您也能通过这个名字从DOM元素中获得它。一个DOM元素可以有多个 Bihavior与之相关联。下面的例子展示了如何使用RTM版本中新增的 $create和 $get,通过一个DOM元素来得到它的Control对象和Behavior对象的引用。如下:
//
Add a control and behavior to the GoShopping DOM element.
$create(Custom.UI.Button, {}, {'click':'myHandler'}, {}, $get('GoShopping'));
$create(Custom.UI.BorderBehavior, {'name':'border'}, {}, {}, $get('GoShopping'));
// Page developer accesses Button using the DOM element directly.
var gs = $get('GoShopping');
gs.control.set_text('Sale items');
gs.border.set_color('red');
// Page developer obtains the behavior using the $ separator.
var bb = $find(‘GoShopping$border);
$create(Custom.UI.Button, {}, {'click':'myHandler'}, {}, $get('GoShopping'));
$create(Custom.UI.BorderBehavior, {'name':'border'}, {}, {}, $get('GoShopping'));
// Page developer accesses Button using the DOM element directly.
var gs = $get('GoShopping');
gs.control.set_text('Sale items');
gs.border.set_color('red');
// Page developer obtains the behavior using the $ separator.
var bb = $find(‘GoShopping$border);
Creating and Finding Components and Elements
在CTP版本中,您能够使用JavaScript来实例化一个对象,设置属性,并调用 initialize方法。另外,您也可以使用XML-Script来操作它。在RTM版本的模型中:
- 能够使用以前一样的方式使用Javascript操作组件。
- 使用新的$create别名来操作组件。它的功能覆盖了实例化对象,设置属性,调用initialize方法等操作。这是一个强大的模型,也能被服务器控件所使用。
- 使用Value-add包中的XML-Script支持,能够在RTM版本中使用与$create功能相同的操作。
$object, $find and $create Aliases
在CTP版本中,我们能够使用 $object('GoShopping')来获得一个被XML-Script初始化的组件引用。Value-add包提供了这个操作。
在RTM版本的代码中,我们引入了 $find方法。您能够使用这个方法来获得任意组件的引用——无论它是使用XML-Script还是 $create初始化的。这意味着我们能够使用它来获得服务器端控件或Extender创造的对象,自然也包括使用JavaScript和XML-Script创造的对象。
Comment 我对这里的说法做一些补充。虽然Behavior会获得一个默认的UniqueID,但是如果一个控件里同时存在两个相同的Behavior会出现什么情况呢?如果同时存在两个不同的,但是名称相同(所在namespace不同)的Behavior,又会如何呢?只有尝试了或者分析代码之后才能知道。因此最好还是为每个需要find到的Behavior提供一个名字。这样就能像之前的例子一样,通过$find('GoShopping$border')来获得。Note:Beta版本中的$find方法能够通过ID来获得一个注册在Application中的组件,Behavior和控件。控件的ID和DOM元素的ID相同。而Behavior能够通过它所在的元素ID和它的类名得到一个默认的UniqueID(“elementId$ClassName”)——例如AddressLine1$AutoCompleteBehavior。
$ and $get
在CTP版本中定义了一个全局的 $()来提供 document.getElementById()的功能。但是无论是RTM版本还是Value-add包已经取消了对它的支持。这么做的原因是为了避免与其他使用 $()的AJAX类库产生冲突。在RTM版本中提供了 $get函数来替代原有的 $()函数,它们具有完全相同的功能。
$addHandler and $removeHandler
RTM版本提供的 $addHandler和 $removeHandler操作提供了一个简单的方式创建和移出对DOM元素事件的响应。在之前Button的例子中已经演示了它们的使用方式。请注意,传递给Handler的参数是个 Sys.UI.DomEvent对象,它是一个跨浏览器的事件对象。在CTP的模型中,您使用全局的 window.event对象进行操作,这并不是一个平台无关的对象。
Comment 虽然window.event不是个平台无关的对象,但是它依旧在多个浏览器运行良好,因为Atlas的Compact层为Event对象作了扩展,使它兼容了IE的操作。
Application Object and Life Cycle
在CTP版本中存在着 Runtime和 Application两个对象的概念。其中 Application对象负责分发window的事件,并且响应开发人员的 pageLoad(通过 load事件)和 pageUnload(通过 unload事件)的功能。 pageLoad的功能保证了这些代码在所有的脚本和XML-Script已经被加载和初始化完毕后才被调用。
在RTM版本中将原来的 Runtime对象和 Application对象结合在了一起,成为了一个新的 Application对象。在RTM版本中依旧保留了 load和 unload事件,另外还引入了新的 init事件,一般用于使用 $create来建立对象。您也可以像以前那样响应 load事件来初始化对象。在RTM版本中,load事件在页面局部刷新的场景中也会被触发,因此如果您在pageLoad时操作对象的话,可能会由于round trip而重建对象。
使用 $create语法在初始化对象时,保证了在实例化对象后调用了 beginUpdate方法,然后设置属性,再依次调用了 endUpdate和 initialize方法。此外,对象被注册到了 Application对象上,因此允许使用 $find来找到这个对象的引用。
Property Change Notification
CTP版本和RTM版本都定义了property-change事件。在RTM版本中,如果您在开发组件,请在属性改变之后为其触发property-change事件,它提供了对于binding功能的支持,并能通知其他的事件监听器。
基础的 Component类型已经实现了 INotifyPropertyChange接口。
Disposing
在CTP版本中,基础类型 Sys.Component已经实现了 Sys.IDisposable接口,因而定义了 dispose方法。这个模型在RTM版本中得到延续。不过在RTM版本中引入了一个新的接口: Sys.INotifyDisposing,它已经被 Sys.Component实现了。这个接口允许Value-add包中的binding来监听一个对象的销毁,因此能够在合适的时候从组件上分离。
支持 UpdatePanel功能的对象必须被销毁,因此您必须正确地实现它们的 dispose方法以避免多次调用而产生的错误。例如在之前的 Button示例中, dispose方法在调用 $removeHandler和 delete之前进行了检查,以确定click handler的存在。
同时您也应该保证,在销毁任意的子组件或者对象前,要对它们进行检查,因为 Application对象无法保证自动销毁对象时的顺序。
Bindings and Actions
在CTP版本中能够为一个组件定义Binding。因此只有存在一个组件,才能将Binding添加给它。
在RTM版本中并没有直接对Binding提供支持,但是提供了 Sys.INotifyDisposing接口。有了这个接口,在Value-add包中的Binding就能在某个对象被销毁时得到通知,以此进行自我管理。因此,Value-add包中的Binding就能够脱离RTM包中组件运行,这也意味着与CTP版本相比,现在的Binding能够更加自由地进行声明和使用。
现在,Value-add包中的Binding能够获取一个source和一个target对象的引用,并且可以监听它们的销毁事件。当其中一个对象被销毁后,为两者建立联系的Binding也能独立地自行销毁。