Reputation: 5613
I know that jQuery isn't designed for working with a class-like model but I really could do with being able to extend a base class as that fits my needs perfectly.
I started by just doing the following:
jQuery.myBase = {
foo: 'bar',
bar: function() { ... }
}
jQuery.fn.myPlugin = function() {
$.extend( this, jQuery.myBase, {
oof: 'rab',
rab: function() { ... }
}
}
That all works fine, I can access the base methods & properties via this
. That is until I try adding something like a jQuery event handler (etc.) which applies the event target to the this
.
So with the following:
jQuery.myBase = {
bar: function() { ... }
}
jQuery.fn.myPlugin = function() {
jQuery.extend( this, jQuery.myBase, {
init: function() {
jQuery('#someEl').click( this.onClick );
},
onClick: function(e) {
// this now references the element I bound the event to (<div id="someEl" />)
// so the following doesn't work
this.bar();
}
}
}
I've found a couple of things for class creation and inheritance that work with jQuery (such as John Resig's one and DUI) but those will/do experience the same issue.
So after all of that, how do I get to the original this
in these situations?
Update: The event handler (etc.) could be in either the jQuery.myBase
or the plugin itself.
Upvotes: 1
Views: 762
Reputation: 5613
It looks like they are addressing this in jQuery which should be part of 1.3.3 according to the comments
Upvotes: 0
Reputation: 5613
Another alternative would be to follow prototypes method of having a bind()
function (which actually does the same as my other answer but in a cleaner fashion), as pointed out in this question, e.g.:
if (!Object.bind) {
Function.prototype.bind= function(owner) {
var that= this;
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner,
args.length===0? arguments : arguments.length===0? args :
args.concat(Array.prototype.slice.call(arguments, 0))
);
};
};
}
jQuery.fn.myPlugin = function() {
jQuery.extend( this, jQuery.myBase, {
init: function() {
jQuery('#someEl').click( this.onClick.bind( this ) );
},
onClick: function(e) {
this.bar(); // this works
}
}
}
Upvotes: 0
Reputation: 82483
You need a reference to it in the appropriate scope.
jQuery.fn.myPlugin = function() {
var $this = this; // Scope it up!
jQuery.extend( this, jQuery.myBase, {
init: function() {
jQuery('#someEl').click( this.onClick );
},
onClick: function(e) {
$this.bar();
}
}
}
Upvotes: 2
Reputation: 5613
The only way that I've thought of doing this, which I don't really like and thus asking the question, is with the following:
jQuery.myBase = {
bar: function() { ... }
}
jQuery.fn.myPlugin = function() {
jQuery.extend( this, jQuery.myBase, {
init: function() {
var self = this;
jQuery('#someEl').click( function(e) {
this.onClick.apply( self, arguments );
};
},
onClick: function(e) {
// this works
this.bar();
}
}
}
Upvotes: 0