前言:
所有的jQuery UI的控件和交换都是基于一个简单的,可重用的jQuery UI控件工厂。它使用一个一致的api作为一个插件可伸缩的基础,来生产复杂,有状态的插件。它被设计为不仅仅作为jQuery UI控件的一部分,而且可以作为不想重构公共组件生成面向对象组件的开发者的一般工具。它不依赖其他的jQuery UI,但是大多数的jQuery UI依赖它。
它是什么
控件的工厂是一个在全局jQuery对象上的一个简单的方法,它有2个或者3个参数。 jQuery.widget( "namespace.widgetname", /* 可选的 - 一个已经存在的组件的prototype来继承 */, /* 传递到组件prototype有一系列的属性组成的对象*/ {...} );
第一个参数是一个包含一个命名空间和组件名称的字符串,通过"."来分割。命名空间必须有,它指向widget prototype存储的全局jQuery对象(fuck这什么意思啊) . 如果命名空间没有,widget factory将会为你生成。widget name是插件函数和原型的真实名称,比如: jQuery.widget( "demo.multi", {...} ) 将会生成 jQuery.demo , jQuery.demo.multi , and jQuery.demo.multi.prototype .
第二个参数(可选)是 widget prototype继承于什么对象。例如jQuery UI有一个“mouse”的插件,它可以作为其他的插件提供的基础。为了实现这个所有的基于mouse的插件比如draggable, droppable可以这么做: jQuery.widget( "ui.draggable", $.ui.mouse, {...} );如果没有这个参数,widget默认继承自“base widget” jQuery.Widget(注意jQuery.widget 和 jQuery.Widget不同) 。
widget factory的最后一个参数是一个对象文字,它会转化为所有widget实例的prototype。widget factory会生成属性链,连接到她继承的widget的prototype。一直到最基本的 jQuery.Widget。
一旦你调用jQuery.widget,它会在jQuery prototype ( jQuery.fn )上生成一个新的可用方法对应于widget的名字,比如我们这个例子jQuery.fn.multi。 .fn方法是包含Dom元素的jquery对象和你生成的 widget prototyp实例的接口,为每一个jQuery对象生成一个新的widget的实例。
更多一点 在Plugin Authoring Guidelines(英文:http://docs./Plugins/Authoring 中文:http://xxh123./blog/1103545)中说了很多实现有状态,面向对象插件的方法。但是它没有给避免普通的plumbing任务提供方便。widget factory给你提供了 jQuery UI的API,与你的插件的实例来交互,并且抽象了一系列的重复任务。
通过namespace和name生成一个伪选择器,可以这样查询:$( ":demo-multi" )。
通过使用jQuery.widget.bridge来实现。
默认的值是暴露的,所以用户可以修改默认的值
实例对象的属性this.element是一个包含Dom元素的jQuery对象的引用,所以从对象到元素或者元素到对象的转换比较的简单。
用户可以定义一个选项 $("#something").multi({clear: function(event) }});
或者使用.bind() $("#something").bind("multiclear", function( event ) {});
实例化后简化和修改插件选项的方法: $( "#something" ).multi( "option", "clear" , function ( event ) { alert( "I cleared the multiselect!" ); } );
很容易enable或者disable widget,或者整体实力的销毁和返回元素的元素状态。
构建自己的属性
基础
你给widget factory传递的对象,可以作为你需要的复杂的widget属性。但是最起码需要default options , and basic _create , _setOption , and destroy callbacks。 Js代码
在方法中包装 传递的对象也许也需要包含方法来处理各种各样的插件具体的功能。比如创建和增加新元素或者处理事件。你可以使用一些别的方法来处理每一个功能 而不是所以的代码都放在_create中。这样你可以避免当功能修改的时候重复代码。比如hypothetical的控件增强了<select multiple>,它必须迭代select中的option选项,而且生成对应的<li> in aproxy </li>,这个可以在_create方法中实现,像这样:
Js代码
不幸的是把代码留在_create,会造成原始的<option>元素和list items之间的管理的困难。或者在控件实例化后处理从原始的<select>增加或者删除<option>状态的问题。代替我们 使用一个refresh方法来负责专门处理这一功能,并在_create中引用。我们当然可以把在元素上处理点击事件的逻辑独立。而且我们使用delegate来避免当新元素创建的时候的重复绑定。
Js代码
私有和公共方法
你也许注意到一些方法以“_”开头,一些不是。以“_”开头的方法被当作jQuery UI的私有方法。控件工厂将会阻止$.fn调用私有方法。 $( "#something" ).multi( "_create" )会扔出一个异常。方法直接在widget prototype上存在,然而这个只是协定的私有方法。当我们使用widget的实力的data()方法的时候,我们可以直接访问他们$("#something" ).data( "multi" )._create() . 那么怎么做更好的?如果控件的使用者需要一个特别的方法的功能,使用public。在一点上举个例子:如果用户处理原始的<select>中的元素,我们必须为来提供方便来更新代理。另一方面,一个plumbing方法来处理widget创建的代理元素。比如 _itemClick,它只是中间使用,所以使用私有方法。
属性
this.element
它是插件的实例化元素。比如,如果你是使用$("#foo").myWidget(),让后在你你的控件对象中this.element是一个包含id为foo的元素的jquery对象。当你选择了多了元素,并在集合上调用.myWidget(),会为每一个元素生成一个插件的实例,总而言之,this.element总是只包含一个元素。
this.options
options被用作插件的配置,用户提供的options会自动的覆盖 $.demo.multi.prototype.options中的默认的options。
this.namespace
就是插件的命名空间,一般不需要在独立插件的内部使用。
this.name
就是插件的名字,比如我们的"multi",比命名空间有用多了,但是在一般在独立插件的内部也不使用。
this.widgetEventPrefix
它被用来决定事件的名称和插件提供的callbacks的关联。比如dialog有一个close的callback,当close的callback被执行的时候,一个dialogclose的事件被触发。事件的名称和事件的prefix+callback的名称。widgetEventPrefix 默认就是控件的名称,但是如果事件需要不同的名称也可以被重写。比如一个用户开始拖拽一个元素 我们不想使用draggablestart作为事件的名称,我们想使用dragstart,所以我们可以重写事件的prefix。如果callback的名称和事件的prefix相同,事件的名称将不会是prefix。它阻止像dragdrag一样的时间名称。
this.widgetBaseClass
在widget里在元素上生成类名非常有用,比如如果你想标记一个元素是否有效,你可以 element.addClass( this.widgetBaseClass + "-active" ),这个在独立的插件中没有需要,因为你可以非常容易的使用.addClass( "demo-multi-active" )。但是它更多的使用在控件的内部和抽象的插件比如$.ui.mouse.
方法:
_create
这个是创建和你的空间相关的所有的东西,比如创建元素,绑定事件。这个方法在实例化后立刻运行一次。
_init
你的控件在调用时没有参数或者一个options参数,这个方法被调用。它可以在_create调用后第一次调用。也可以在控件生成后的任何时间调用那样,_init允许你重写初始化,而不必强制用户调用destroy->create的循环.
destroy
这个destory插件的对象和其他必要的清理。任何插件造成的修改必须被remove和destroy。包括消除类,解绑定事件,销毁生成的元素。控件工厂提供了一个开始的地方,但是应该满足所有的独立插件的需要。
option
用来在实例化后初始和设置options。方法的用法和jquery的.css()或.attr()一样。可以指定一个名字来获取值和设置值。这个方法通常被称作_setOptions 所以这个方法应该永远不被插件修改。
_setOptions
是一个通用的工具作为实例化后的设置options。它不应该被插件修改。
_setOption
通过option方法设置一个option值的时候被调用,也许这个方法在独立的插件中需要给修改,所以当某些选项修改是插件可以对应。比如title option修改是,title的内容应该更新。
Js代码
通过调用基本的_setOption方法,可以把option的值设为新值。这个不应该用_setOption设置。在某些实例中需要判断新值和旧值那一个是正确的。 在其他的一些实例中,你可以用 this.options[key]和你延迟的基本_setOption比较,直到结束。如果不需要比较,你可以在你的_setOption 上面调用基本的_setOption 。
enable
Helper方法调用option('disabled', false),你也许想通过在_setOption中的 if (key === "disabled")块来处理这个。
disable
Helper方法调用option('disabled', true),你也许想通过在_setOption中的 if (key === "disabled")块来处理这个。
_trigger
这个方法用来执行所有的callbacks。只需要回调函数的名称就可以执行了。所有的回调也触发事件(看上面的widgetEventPrefix ),你也许提供一个事件对象来代表事件的初始化处理。比如一个拖拽事件也许初始化一个鼠标移动的事件。所以原始的鼠标移动事件必须传递 到_trigger中。第三个参数是一个hash的数据传递到回调和事件处理函数。在hash中提供的数据应该具体事件和一些其他的不可读的插件api的信息。
Other Benefits and Use:
使用widget factory的插件仅仅处理插件的实例,不合被调用的jquery的方法一起使用。当你从一个jquery object上调用插件的一个方法。widget factory通过调用合适的插件实例来代理方法。它也会自动的处理链式,如果方法返回插件的实例,widget factory会在每一个插件对象上链式调用。如果返回的哦不是插件的实例,它会从原始的jqueyr对象上返回值。
引用
http://docs./Plugins/Authoring
http://xxh123./blog/1103545
http://wiki./w/page/12138135/Widget-factory
http://dingchao-lonton./blog/1402280
|
|
来自: nikybook > 《JavaScript》