Bug Tracker

Opened 9 years ago

Closed 9 years ago

Last modified 8 years ago

#6807 closed enhancement (fixed)

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.

Change History (4)

comment:2 Changed 9 years ago by dareed

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

comment:3 Changed 9 years ago by dareed

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

comment:4 Changed 9 years ago by john

Priority: undecided
Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.