现在的位置: 首页 > easyui > 正文
浅谈jQuery Easyui的继承和依赖原理
2013年01月11日 easyui ⁄ 共 4104字 评论数 2 ⁄ 被围观 15,453 views+
文章目录
[隐藏]

话说,大家都知道jQuery Easyui的各种组件之间是有继承或者依赖关系的,那么大家是否真的理解这里提到的“继承”或者“依赖”的关系了?本文就这两个问题做较为全面的阐述,希望通过本文大家能对easyui的运作机制有更为透彻的理解。继承和依赖关系主要体现在下面三点:

  • 属性的继承
  • 事件的继承
  • 方法的继承

属性的继承:

我们以combo和validatebox组件的关系作为例子,combo的属性继承自validatebox。我们先看combo组件构造函数的代码:

  1. /**  
  2.  * 1.3.2版本combo组件的构造函数  
  3.  * @param {} options  
  4.  * @param {} param  
  5.  * @return {}  
  6.  */  
  7. $.fn.combo = function(options, param) {   
  8.     if (typeof options == "string") {   
  9.         return $.fn.combo.methods[options](this, param);   
  10.     }   
  11.     options = options || {};   
  12.     return this.each(function() {   
  13.         var state = $.data(this"combo");   
  14.         if (state) {   
  15.             $.extend(state.options, options);   
  16.         } else {   
  17.             var r = _e(this);   
  18.             state = $.data(this"combo", {   
  19.                 //唯有此处有继承之嫌疑,可是丝毫看不出combo继承了validatebox什么属性啊,怎么回事呢。   
  20.                 options : $.extend({}, $.fn.combo.defaults,$.fn.combo.parseOptions(this), options),   
  21.                 combo : r.combo,   
  22.                 panel : r.panel,   
  23.                 previousValue : null  
  24.             });   
  25.             $(this).removeAttr("disabled");   
  26.         }   
  27.         //...   
  28.     });   
  29. };  

combo组件的代码里,我们没有捕捉到combo组件继承validatebox组件属性的地方,但是对于这句代码我们还没有深究:

  1. options : $.extend({}, $.fn.combo.defaults,$.fn.combo.parseOptions(this), options)  

我们再来看看combo组件的属性解析器是如何定义的;

  1. /**  
  2.  * 看到了不?是不是心中暗喜,原来藏在这里。  
  3.  * 我们看到combo组件的属性来自于以下几部分;  
  4.  * 1.validatebox组件属性转换器转换解析dom获取到的属性(优先级最低);  
  5.  * 2.公用属性转换器转换指定的几个属性(优先级次之);  
  6.  * 3.写死的panelHeight,multiple,disabled,value(优先级最高)  
  7.  * @param {} target  
  8.  */  
  9. $.fn.combo.parseOptions = function(target) {   
  10.     var t = $(target);   
  11.     return    
  12.     $.extend(   
  13.         {},    
  14.         $.fn.validatebox.parseOptions(target),    
  15.         $.parser.parseOptions(target,    
  16.         ["width""height""separator",    
  17.             {   
  18.                 panelWidth : "number",   
  19.                 editable : "boolean",   
  20.                 hasDownArrow : "boolean",   
  21.                 delay : "number"  
  22.             }   
  23.         ]),    
  24.         {   
  25.             panelHeight : (t.attr("panelHeight") == "auto""auto" : parseInt(t.attr("panelHeight")) || undefined),   
  26.             multiple : (t.attr("multiple") ? true : undefined),   
  27.             disabled : (t.attr("disabled") ? true : undefined),   
  28.             value : (t.val() || undefined)   
  29.         }   
  30.     );   
  31. };  

综合combo的构造函数和combo的属性转换器,我们最终可以得到,combo的属性的属性来源,可以用简单的用下图来表示:

easyui_property_extend

到这里为止,我们对jQuery Easyui组件之间属性的继承方式已经大致理解。其中重点是其继承方式是使用的jQuert的extend函数实现的,所以要想彻底明白,必须对extend函数有足够的了解,当然了这超出了本篇文章的讨论范围,请大家自行翻阅资料。

事件的继承:

在传统的面向对象语言中,事件这个概念并不存在jQuery Easyui的事件其实也就是属性,继承的原理跟属性的继承完全一样,只不过这个属性是个带有函数罢了,开发者可以定义这个函数。然而大多事件最终是通过javascript的call函数来触发的,我们那combo组件的onHidePanel事件来看:

  1. function hiddenPanel(target){   
  2.     var opts = $.data(target, "combo").options;   
  3.     var panel = $.data(target, "combo").panel;   
  4.     panel.panel("close");   
  5.     //用户可以自定义opts.onHidePanel这个函数   
  6.     //在combo的内部方法中会在程序中的适当位置调用这个函数,并且将上下文设置为target   
  7.     opts.onHidePanel.call(target);   
  8. }  

方法的继承:

跟传统面向对象的语言一样,jQuery Easyui组件间的方法也是可以继承的,那么方法又是怎样被继承的呢,我们拿combobox组件的构造函数来分析:

  1. $.fn.combobox = function(options, params){   
  2.     //如果构造函数第一个入参是字符串,则是方法调用。   
  3.     if (typeof options == "string") {   
  4.         //尝试到combobox组件中找这个方法   
  5.         var caller = $.fn.combobox.methods[options];   
  6.         if (caller) {   
  7.             //如果找到了这个方法,则调用之   
  8.             return caller(this, params);   
  9.         }   
  10.         else {   
  11.             //如果没有找到,则调用combo组件的同名方法   
  12.             return this.combo(options, params);   
  13.         }   
  14.     }   
  15.     //...   
  16. };  

官方的API里面说,combobox组件的方法集成自combo组件,这个在combobox组件的构造函数中已经充分体现出来了,jQuery Easyui所谓的继承,只不过是它内部的一种实现方案,并不是真正意义上的“继承”。

同时我们还必须看到方法继承的特殊性,即对用承载combobox组件的target,肯定也承载了combo组件,要不然不可能调用combo组件的方法,所以combobox组件的初始化过程中一定也在target上初始化了combo组件,也就是说,在target上肯定同时存储了名为"combo"和"combobox"的对象:

  1. $.data(target,'combobox')//能取到数据   
  2. $.data(target,'combo')//也能取到数据  

这就好比combo是个汽车人里的“大黄蜂”的汽车状态,那么combobox绝对不是由若干汽车人组成的超级擎天柱,而仅仅是由“汽车状态”变成了“机器人”状态的大黄蜂,换汤不换药,这是方法能够继承的前提。

依赖涵盖继承:

依赖关系不仅仅体现在“继承”上面,也现成在“组成”上面,所以个人概括地用“依赖” == “继承” + “组成”;这个表达式来表示有依赖关系的组件。

我们拿dialog,window,linkbutton三个组件的关系来举例说明:

dialog组件依赖window组件和linkbutton组件。dialog其实就是window,因为他们有方法上的继承;同时window内部有实例化了linkbutton组件。这就好比,“汽车态”的大黄蜂变成了“机器人”状态的大黄蜂,同时一条吉娃娃跳到了它的手掌心,这只吉娃娃就是linkbutton了。

目前有 2 条留言 其中:访客:2 条, 博主:0 条

  1. peislin : 2013年01月11日14:01:55  -49楼 @回复 回复

    认真看了,写的很好!把easyui这一条完全搞懂了,估计js也学的差不多了……

  2. cxntsh : 2013年05月24日15:19:45  -48楼 @回复 回复

    看的很吃力,基本知道怎么回事!加油! 😎

给我留言

留言无头像?


×