YUI3学习笔记之二:自定义事件与AOP

对于我来说,javascript中最有趣而又最无奈的就是事件处理了。丰富前卫的交互体验、流畅便捷的浏览操作,都需要建立在良好的事件处理机制上。然而浏览器的差异在事件处理上达到了最大化,内存泄露在事件处理函数中又最容易引入,这让很多人都对javascript的事件处理很头痛。

自定义事件就很少有这种天然的浏览器差异了。我们日常编码中接触自定义事件的机会也很多,比如一个xhr对象,一般都会定义onsuccess和onfailure等方法来处理xhr的返回结果;一个动画效果也往往会有onstart,onfinish等类似的方法来处理动画变化中的状态。由于我们一般都在编程中使用面向对象思想,很多时候代码会是这样的:

 1 var test = new Ajax({
 2     onSuccess:function(){},
 3     onFailure:function(){},
 4     onCancel:function(){}
 5 });
 6 
 7 
 8 
 9 
10 
11 if(xxx){
12     test.cancel()

13 }  

如上,我们一般会在类里面定义好各种各样的自定义事件,然后程序会自动帮我们完成一些诸如onSuccess的函数,或者我们也可以主动调用实例的相关方法。

看似不错吧。不过如果我们有很多个这样的需求,就会有很多个这样的实例。实例多了不仅不好看,而且也很占内存。同时,这样的复用性也不见得多好。比如,我们需要很多实例,他们都用公共的一些事件处理方法,但同时又有各自的不同,我们如何实现呢?是生成多个只有细节不同的实例,还是继承一下Ajax,定义好公共方法,然后再实例化各个不同?前一种方法显得很不优雅,而后一方法则显得不是那么适合Javascript的编程,同时也会有类过多、实例过多的问题。

 

曾经的YUI2也是采用这样的方式。 YUI3则抛弃了OOP思想,引入了AOP思想,也就是面向切面编程,解决类似的问题。

关于AOP的解释可以看这里:http://en.wikipedia.org/wiki/Aspect-oriented_programming

通俗的讲,OOP中模型是这样:

实例.传输成功    ,   实例.传输失败 

而到了AOP中变成了这样:

传输.成功(实例甲)    ,   传输.失败(实例乙)

 

即,我们把一个纵向的流水关系,从中垂直劈开一个平面,由这个切面去处理各个事件。 这样,我们可以通过操作切面,达到统一切面方法的目的。各个实例各自的方法,又可以造成最后成果的区别。

我们来看看yui3中对于ajax的处理。

对于上面提到了各个实例需要的公共事件处理,我们可以这样定义:

1 YUI.use( 'io-base' , function(Y){
2 
3     Y.on("io:success" , function(){} , thistrue );
4 
5     Y.on( "io:failure" , function(){} , this );
6 
7     Y.io(url);
8 

9 }  );  

 

是不是很优雅,而对于特殊的事件,我们可以做如下处理:

 1 .
 2 
 3 var cfg = {
 4     on: {
 5         success:function(){}
 6         failure:function(){}
 7 
 8     }
 9 };
10 
11 Y.io(url,cfg);
12 
13 
14 .
15 


是的,只要给Y.io传入一个新参数,定义好特殊的方法,就可以实现刚才OOP很难实现的问题了。

YUI3把AOP思想作为了一种内建的思想,除了最基础的模块外YUI3都引用了event-custom这一模块来优化代码。最近就是花了比较多的时间去研究这样一个思想。了解清楚之后,对整个YUI3的代码的了解都会有很大帮助。 

 

posted @ 2009-11-08 21:47  demix  阅读(1138)  评论(0编辑  收藏  举报