Skip to main content

Bug Tracker

Side navigation

#6807 closed enhancement (fixed)

Opened July 20, 2010 07:05PM UTC

Closed September 29, 2010 02:10PM UTC

Last modified March 13, 2012 10:58PM UTC

jQuery.fn.data with JavaScript objects should set fields directly

Reported by: dareed Owned by:
Priority: undecided Milestone: 1.4.3
Component: data Version: 1.4.2
Keywords: data plainobject Cc:
Blocked by: Blocking:
Description

Currently, you can use jQuery.fn.data on plain objects, but the data is stored in a separate cache associated with an expando on the object. For objects, it makes sense for data() to set fields directly on the object and avoid the separate cache. This would make this:

$(obj).data("test", value);

The same as:

obj.test = value;

Except that it would raise the changeData event, opening up some interesting "observable" scenarios such as data linking.

Other uses of data() and data related APIs are interesting, too, and could go a number of different ways. The proposed behavior is:

$(obj).data(); returns obj

$(obj).data({test:value}); same as $.extend(true, obj, {test:value})

$(obj).removeData("test"); same as: delete obj.test

$(obj).removeData(); removes all fields from the object

var obj = { existing: true };

$(obj).data("existing"); // true

Another interesting behavior is with events. This change would cause $(obj).bind(..) to set a field on the object named 'events' with the event handler information (and one called 'handle'). That would be unfortunate when the object is JSON serialized. This problem also exists for uses of data() but is solved by the changes already described. To avoid the 'events' expando from being serialized, this change also modifies how 'events' and 'handle' are stored on plain objects. They are now fields of a 'container' object returned by the 'events' expando. For example:

var fn = $(obj).data("events"), container = fn(), events = container.events, handle = container.handle;

This does somewhat make event handler retrieval more indirect. A few places in event.js had to be changed to call this function if the object is not a dom element, but were done so in an unobtrusive way in the 90% case where it is a dom element.

Also, currently doing "$(obj).data(otherObj)" removes the event handlers for any bound events on the object, since events are stored in the data. They wouldn't be cleared anymore by this operation, since will only 'extend' the wrapped object with the given source object and will leave the 'events' list alone.

Attachments (0)
Change History (4)

Changed July 20, 2010 07:07PM UTC by dareed comment:1

Changed July 22, 2010 10:50PM UTC by dareed comment:2

This change conflicts a bit with the already merged changes to use a function as the expando on plain objects (it isn't necessary to do so since there is no longer any expandos). I've resolved the merge conflicts:

http://github.com/nje/jquery/tree/DataPlainObject

Changed September 28, 2010 01:18AM UTC by dareed comment:3

It's gone a bit stale and there were some conflicts I'd rather not have worked out, so I reimplemented it in a fresh branch:

http://github.com/nje/jquery/tree/data-plain-object

Changed September 29, 2010 02:10PM UTC by john comment:4

priority: → undecided
resolution: → fixed
status: newclosed