I'm interested on how is realized the JavaScript pattern used, for example, in jQuery UI dialog:
$.dialog('mydialod').dialog('close');
ie I can't get how to reference back a constructor function after I created it in a jQuery compliant fashion.
EDIT
Just to clarify: what is really obscure to me is how I can have somewhere
$('#mydlg').dialog();
and then somewhere else
$('#mydlg').dialog("somecommand");
that even in absolutely different places seems to point back to the original instance. I think, it is somehow related with this (jquery.ui.widgets.js ),
// create selector for plugin
$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
return !!$.data( elem, fullName );
};
but really I'm too green in javascript / jquery to get what's happening.
I'm not sure how jQuery UI does it (you'd have to look at the source), but here's a way to do this https://gist.github.com/elclanrs/5668357
The advantage of using this approach is that you keep all your methods private instead of in the prototype by using a closure; a module pattern in this case.
Edit: Aight, got it. This is how I got it to work. This I'm calling the "Advanced jQuery Boilerplate". I added the methods to the prototype, I don't think it really makes a difference to keep them outside, and makes it easier to call methods within methods with this.method()
:
(function($) {
var _pluginName = 'myplugin'
, _defaults = {
};
function Plugin(el, options) {
this.opts = $.extend({}, _defaults, options);
this.el = el;
this._init();
}
Plugin.prototype = {
_init: function() {
return this;
},
method: function(str) {
console.log(str);
return this;
}
};
Plugin.prototype[_pluginName] = function(method) {
if (!method) return this._init();
try { return this[method].apply(this, [].slice.call(arguments, 1)); }
catch(e) {} finally { return this; }
};
$.fn[_pluginName] = function() {
var args = arguments;
return this.each(function() {
var instance = $.data(this, 'plugin_'+ _pluginName);
if (typeof args[0] == 'object') {
return $.data(this, 'plugin_'+ _pluginName, new Plugin(this, args[0]));
}
return instance[_pluginName].apply(instance, args);
});
};
}(jQuery));
Now I have two divs:
<div></div>
<div id="mydiv"></div>
And I can use the plugin like:
$('div').dialog({ n: 69 }); // initialize both divs
console.log($('#mydiv').dialog('method', 'hello world'));
//=^ prints "hello world" and returns instance
console.log($('#mydiv').data('plugin_dialog').opts.n); //=> 69
It's basically storing the instance of the plugin in data
to be able to restore the options since this info is attached to the element. It's similar to how jQuery Boilerplate works.
This is called 'chaining pattern'. Basic idea is that object methods return constructed instance, look at simplified example:
function Dialog (){
this.open = function(){
console.log('open dialog');
return this;
}
this.close = function(){
console.log('close dialog');
return this;
}
}
var d = new Dialog();
d.open().close();
Note 'return this' statement in every method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With