在发布事件时,我们可以添加所有在事件对象中监听器所需要的信息,例如: this.fire(‘help’, {helpTopic: ‘Event Broadcasting’});
fire()方法的两个参数分别为发布事件的名称(也就是Y.Base为它增加前缀的类的名称)和包含一些特性的对象(这些特性需要复制给事件对象)。这样监听器就不需要为了获取一些信息而遍历注册事件模块,从而达到了松耦合的目的。监听器通过“事件广播”知道有这样的一些模块,甚至可能有很多这样的模块会响应help事件,但并不需要关注是哪一个模块正在响应它。这种方法也简化了日后新模块的添加。
事件和默认行为
要改变一个类的行为,通常的办法是建立一个子类,然后重写它的方法。YUI也可以完成这些工作。你可以用Y.Base.create来创建一个基类Y.Widget,然后用Y.Base.create来创建一个新的类来作为基类的扩展,并给予其一些特殊的行为。例如,先创建基类: Y.MySimpleWidget = Y.Base.create( ‘simpleWidget’, Y.Widget, [], { // instance members here, amongst them: renderUI: function () { this.get(CBX).append(Y.Node.create(‘ … whatever goes into the widget … ‘ )); } }, { ATTRS: { // configuration attributes } // other static members } );
然后创建子类: Y.MyFancyWidget = Y.Base.create( ‘fancyWidget’, Y.MySimpleWidget, [], { renderUI: function () { Y.MyFancyWidget.superclass.renderUI.apply(this, arguments); this.get(CBX).append(Y.Node.create(‘ … add some bells and whistles … ‘ )); } // Presumably the fancy version does not need any further static members so I skip the last argument );
我们可以看到,MyFancyWidget通过添加一些细节改进了MySimpleWidget。但是这在某些情况下会有些问题,所以你需要设计一个更灵活,更容易改变的基类。自定义事件会对你有所帮助。
假设有个排序类,拥有key和direction两个参数,声明如下: sort: function (key, direction) { // sorting happens here },
如果这个函数的行为在某些情况下需要更改,您可以这么做,在initializer方法中添加自定义事件: initializer: function (config) { // amongst many other things: this.publish(SORT, {defaultFn: this._defSortFn}); },
若SORT是一个具有排序功能的实例,你可以这样声明它的sort函数: sort: function(key, direction) { this.fire(SORT, {key:key, direction:direction}); },
这样子,排序函数就转换为一个具有相同参数的事件触发函数。这样只是提供了一个转换接口,你仍然需要通过原始的排序函数来设计一个类: _defSortFn: function (ev) { var key = ev.key, direction = ev.direction; // same code as the original sort function },
这个_defSortFn类的函数体与原始的方法一模一样,达到相同的排序目的。但是你可以从事件对象中知道key和direction参数,只要一段简单的代码段就可以设置一个监听器,并且改变排序方法。 myObjectThatSorts.on(‘sort’, function (ev) { var key = ev.key, direction = ev.direction; ev.preventDefault(); // now do your own sort });
通过preventDefault我让myObjectThatSorts不再执行_defSortFn中的排序方法,从而可以根据我需要的结果做任何事,无论原来的排序是什么样。我甚至不用关心它是否停止,只要监听after事件来翻转UI上用来显示排序方向的箭头。
我也可以改变事件对象。当事件触发时,我们得到的是根据事件对象复制的一个对象,它从before监听器开始传播,通过默认的函数,到达after监听器,然后被丢弃。你可以在过程中改变它的一些属性的值。当然,在默认方法执行后再做任何改变是没有影响的,在执行之前改变事件对象才能对方法有所影响。例如。 myObjectThatSorts.on(‘sort’, function (ev) { ev.direction = (ev.direction===’desc’?'asc’:'desc’); });
这样将得到倒置的排序结果。
出处:Taobao.com UED Team
责任编辑:bluehearts
上一页 使用YUI 3开发Web应用的诀窍 [7] 下一页 使用YUI 3开发Web应用的诀窍 [9]
◎进入论坛网页制作、WEB标准化版块参加讨论,我还想发表评论。
|