jquery-ui 分析2

          今天由于分析jquery-ui-multiselect 再次读了jquery.ui.widget的代码;读完后很不淡定啊,其实我在想一个事情:jquery 的代码太灵活了,jquery-ui的核心依赖jquery.ui.widget的代码写的近乎诡异哦,太人才喽,哥要不要去学学面向对象的js框架比如dojo?

            闲话不扯,先弄懂jquery-ui吧。简单写写学到的知识:

jquery -ui的插件体系里,所有的控件都依赖于ui.core 和ui.widget,是不是都继承他俩?这个“继承”看起来真的不能滥用哦。“继承“的感觉还真是不明显!

1:创建插件对象

        $.widget.bridge 这个方法给了我们一段通用的创建对象的方法,什么dialog,progressbar等等都通过这个方法调用对象,看起来有点像继承,呵呵,不过真不是。

        

 1 $.widget.bridge = function( name, object ) {
 2     var fullName = object.prototype.widgetFullName || name;
 3     $.fn[ name ] = function( options ) {
 4         var isMethodCall = typeof options === "string",
 5             args = slice.call( arguments, 1 ),
 6             returnValue = this;
 7 
 8         // allow multiple hashes to be passed on init
 9         options = !isMethodCall && args.length ?
10             $.widget.extend.apply( null, [ options ].concat(args) ) :
11             options;
12 
13         if ( isMethodCall ) {
14             this.each(function() {
15                 //如果是方法调用。。。。
16                 }
17             });
18         } else {
19             this.each(function() {
20               //非方法调用的时候。。。。
21             });
22         }
23 
24         return returnValue;
25     };
26 };

  第三行:$.fn[ name ]

 实际上相当于$.fn.命名空间, 好,一般读过插件代码的都知道它是用来创建新插件的。

第4,5行代码:

 var isMethodCall = typeof options === "string",
  args = slice.call( arguments, 1 ),
对第一个参数进行判断,如果是string,表明这是方法调用。
args = slice.call( arguments, 1 ), 是获得第一个参数后面的参数。

2: 方法调用

2:方法调用;
通常我们写java,C#代码,方法调用是这样的:
new 类名().方法名(“参数”);
但是我们在实现jquery插件系统的时候,往往是这样:
$("selector").namespance("方法名",[参数列表])  比如: $("div").button("open");

这么做看起来很奇怪,不过据翻阅各种资料,它的重要作用是防止命名空间的污染。
看这样一段代码:
假如写一个tooltip的插件:

1 (function( $ ){ 
2 
3 $.fn.tooltip = function( options ) { // 这样 }; 
4 $.fn.tooltipShow = function( ) { // 是 }; //显示tooltip
5 $.fn.tooltipHide = function( ) { // 不好的 }; //隐藏tooltip
6 $.fn.tooltipUpdate = function( content ) { // 同学! }; //。。。
7 
8 })( jQuery );

我们想这样写代码:

$("<div>").tooltip();
$("<div>").tooltipShow();
这样的危险在于,可能有人写了一个东东,
比如:
$("<div>").tooltipShow=function(){
  func1:function(){}
}
好吧,直接的结果是,原来的代码$("<div>").tooltipShow();挂掉了。

3: 可以覆盖的方法
在jquery.ui.widget 中有些方法一般都会被基于它的控件所覆盖:


destroy():将widget实例从dom对象上移除,在开发widget的时候一般此方法是必须的。就是移除你自己在dom element上添加的样式和行为以及dom结构

options:在这里面保存的是widget的配置信息,在创建widget的时候需要设置一些配置参数。

element:就是widget作用的dom对象。

enable()和disable()这两个方法就是禁用和启用widget的。其实是修改options.disabled。

还有两个私有方法是创建widget的时候要重写的。

_create() 这个方法就是创建widget的方法,在页面调用widget的时候,就会执行此方法,来构建widget。Widget的绝大大多数行为和结构都是在这里创建的。

_init() ;

_create()方法在widget构建的时候执行,而_init()方法在构建和重新初始化的时候执行。而destroy方法则是在移除widget的时候被执行。在widget中,所有的私有方法都将加以"_"前缀

_setOption():此方法提供了options的属性的设置,一般情况下如果options里面的参数不需要特殊处理(校验,类型转换,以及设置属性的时候触发某一操作等)的时候不需要对此方法进行重写

分析widget的源码可以看到:  

_create: $.noop,
_init: $.noop,

明摆着是让子控件来重写[不是调用哦]的,呵呵!然而,重写某些方法,可能会带来灾难性后果哦,比如_createWidget,看来jquery-ui对某些方法保护做的不好

前缀为"_"的方法,一般可以认为是私有方法,子控件调用不得。

    因为有这段代码: 

    if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
        return $.error( "no such method '" + options + "' for " + name + " widget instance" );
    }

比如:

 // 这行代码不会执行控件的任何方法
 $("button").button("_create"); 

 

posted on 2013-05-24 14:40  xinchuang  阅读(1424)  评论(0编辑  收藏  举报