Reputation: 2036
I've been developing a jQuery widget using the widget factory.
All is well except I've noticed that if I instantiate the widget on more then one DOM element on the same page, any object within the widget is shared between the DOM elements EXCEPT for the options object.
I thought that all objects and functions had their own instance within the widget. I'm obviously missing something and would appreciate some guidance.
For example:
(function($) {
$.widget("a07.BearCal", {
options: { className : "test" },
_glbl: { something: "" },
_create: function() {
this._glbl.something = this.element.attr('class');
this.options.className = this.element.attr('class');
},
});
})(jQuery);
// Instantiate widget on .full
$('.full').BearCal();
//Should output full
console.log($('.full').data('BearCal')._glbl.something);
//Should output full
console.log($('.full').data('BearCal').options.className);
// Instantiate widget on .mini
$('.mini').BearCal();
//Should output mini
console.log($('.mini').data('BearCal')._glbl.something);
//Should output mini
console.log($('.mini').data('BearCal').options.className);
//Should output full but outputs mini
console.log($('.full').data('BearCal')._glbl.something);
//Should output full
console.log($('.full').data('BearCal').options.className);
Working example of this: http://jsfiddle.net/NrKVP/4/
Thanks in advance!
Upvotes: 0
Views: 335
Reputation: 434975
The properties of your widget:
$.widget("a07.BearCal", {
// The stuff in here...
});
get attached to your widget's prototype. The widget factory knows about options
and knows that it needs to duplicate them per-widget: your options
are behaving as you expect because the widget factory arranges for this behavior. The widget factory doesn't know anything about _glbl
so it gets left on the prototype and thus shared by all instances of your widget.
You can duplicate your _glbl
yourself if you want per-widget copies:
this._glbl = { something: this.element.attr('class') };
That will give you a different _glbl
object on each widget.
Demo: http://jsfiddle.net/ambiguous/UX5Zg/
If your _glbl
is more complicated, then you can use $.extend
to copy it and merge something
in:
this._glbl = $.extend(
{ },
this._glbl,
{ something: this.element.attr('class') }
);
You'll want to use true
as the first argument to $.extend
if you need a deep copy. The empty object, { }
, is needed as $.extend
will merge everything into its first object argument and you want a fresh copy.
Demo: http://jsfiddle.net/ambiguous/pyUmz/1/
Upvotes: 2