If you liked the idea of generating plug-ins based on
objects in the last design pattern, then you might be interested in a
method found in the jQuery UI Widget Factory called $.widget.bridge
.
This bridge basically serves as a middle layer between a JavaScript
object that is created using $.widget
and the jQuery core API, providing a more built-in solution to achieving
object-based plug-in definition. Effectively, weâre able to create
stateful plug-ins using a custom constructor.
Moreover, $.widget.bridge
provides access to a number of other capabilities, including the
following:
Both public and private methods are handled as one would expect in classical OOP (i.e., public methods are exposed, while calls to private methods are not possible).
Automatic protection against multiple initializations.
Automatic generation of instances of a passed object and storage of them within the selectionâs internal
$.data
cache.Options can be altered post-initialization.
For further information on how to use this pattern, please see the inline comments below:
/*!
* jQuery UI Widget factory "bridge" plugin boilerplate
* Author: @erichynds
* Further changes, additional comments: @addyosmani
* Licensed under the MIT license
*/
// a "widgetName" object constructor
// required: this must accept two arguments,
// options: an object of configuration options
// element: the DOM element the instance was created on
var
widgetName
=
function
(
options
,
element
){
this
.
name
=
"myWidgetName"
;
this
.
options
=
options
;
this
.
element
=
element
;
this
.
_init
();
}
// the "widgetName" prototype
widgetName
.
prototype
=
{
// _create will automatically run the first time this
// widget is called
_create
:
function
(){
// creation code
},
// required: initialization logic for the plug-in goes into _init
// This fires when our instance is first created and when
// attempting to initialize the widget again (by the bridge)
// after it has already been initialized.
_init
:
function
(){
// init code
},
// required: objects to be used with the bridge must contain an
// "option". Post-initialization, the logic for changing options
// goes here.
option
:
function
(
key
,
value
){
// optional: get/change options post initialization
// ignore if you don't require them.
// signature: $("#foo").bar({ cool:false });
if
(
$
.
isPlainObject
(
key
)
){
this
.
options
=
$
.
extend
(
true
,
this
.
options
,
key
);
// signature: $( "#foo" ).option( "cool" ); - getter
}
else
if
(
key
&&
typeof
value
===
"undefined"
){
return
this
.
options
[
key
];
// signature: $( "#foo" ).bar("option", "baz", false );
}
else
{
this
.
options
[
key
]
=
value
;
}
// required: option must return the current instance.
// When re-initializing an instance on elements, option
// is called first and is then chained to the _init method.
return
this
;
},
// notice no underscore is used for public methods
publicFunction
:
function
(){
console
.
log
(
"public function"
);
},
// underscores are used for private methods
_privateFunction
:
function
(){
console
.
log
(
"private function"
);
}
};
Usage:
// connect the widget obj to jQuery's API under the "foo" namespace
$
.
widget
.
bridge
(
"foo"
,
widgetName
);
// create an instance of the widget for use
var
instance
=
$
(
"#foo"
).
foo
({
baz
:
true
});
// our widget instance exists in the elem's data
// Outputs: #elem
console
.
log
(
instance
.
data
(
"foo"
).
element
);
// bridge allows us to call public methods
// Outputs: "public method"
instance
.
foo
(
"publicFunction"
);
// bridge prevents calls to internal methods
instance
.
foo
(
"_privateFunction"
);
Get Learning JavaScript Design Patterns now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.