I am attempting to move away from spaghetti code in my jQuery plugins and work in a more structured manner.
I am doing so by using the basic boilerplate template found here: https://github.com/jquery-boilerplate/jquery-patterns/blob/master/patterns/jquery.basic.plugin-boilerplate.js
I also found the ToDo MVC plain jQuery code a source of inspiration because it doesn't chain many functions and keeps things nicely separated (I am not allowed to post more than two links due to my lack of status, so you will have to Google that yourself).
All in all I find a combination of the two above quite good to work with, but there seems to be no way to work like this without referencing this
(the root plugin object) quite often. This in itself is not an issue, but sometimes this
becomes out of scope. I haven't really found an elegant way around it, especially when binding event handlers via jQuery on.()
. Please see my JSFiddle for an illustration of what I mean: http://jsfiddle.net/hendrikdegraaf/wzp3ok4h/18/
I find that passing the plugin object in the event.data
object as event.data.base
a bit awkward (it's just very verbose and harms readability of my code). Is there not a better way to reference the main plugin object?
I've had issues with variable scope before when using this way of structuring my plugin, so any general advice on how to structure my plugins in a sensible way would be appreciated as well.
Thanks,
Hendrik
EDIT: Please see my code below
;(function ( $, window, document, undefined ) {
// Create the defaults once
var pluginName = "myplugin",
defaults = {
settingA : 'someValue',
settingB : 'someValue'
};
// The actual plugin constructor
function Plugin(params) {
params.options = $.extend( {}, defaults, params.options);
this.params = params;
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype = {
init: function () {
var base = this; // cache the context so we can still reference it when entering new context
this.cacheElements();
this.bindEvents(base);
},
cacheElements : function (base) { //cache elements
this.$el = $('div.doSomething');
},
bindEvents : function (base) { // bind some touch functions to touch events, and modal window hidden event
this.$el.on('click', {base: base}, this.myFunction);
},
myFunction : function () {
console.log(this); //this now refers to $el
}
};
// A really lightweight plugin wrapper around the constructor,
// preventing against multiple instantiations
$.fn[pluginName] = function ( params ) {
return this.each(function () {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName,
new Plugin(params));
}
});
};
})( jQuery, window, document );