Skip to content
Permalink
Browse files
Ticket #6804. Adds a changeData event.
  • Loading branch information
InfinitiesLoop authored and jeresig committed Jul 20, 2010
1 parent 6a0942c commit 2e10af143b7eafb7142524f6534a62aee1910bd1
Showing 2 changed files with 21 additions and 5 deletions.
@@ -129,6 +129,7 @@ jQuery.fn.extend({
} else {
return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
jQuery.data( this, key, value );
jQuery.event.trigger( "changeData" + parts[1] + "!", [parts[0], value], this );
});
}
},
@@ -68,7 +68,7 @@ test(".data()", function() {
})

test(".data(String) and .data(String, Object)", function() {
expect(23);
expect(27);
var div = jQuery("<div/>");

ok( div.data("test") === undefined, "Check for no data exists" );
@@ -88,11 +88,23 @@ test(".data(String) and .data(String, Object)", function() {
ok( div.data("notexist") === undefined, "Check for no data exists" );

div.data("test", "overwritten");
var hits = {test:0}, gets = {test:0};
var hits = {test:0}, gets = {test:0}, changes = {test:0, value:null};


function logChangeData(e,key,value) {
var dataKey = key;
if ( e.namespace ) {
dataKey = dataKey + "." + e.namespace;
}
changes[key] += value;
changes.value = jQuery.data(e.target, dataKey);
}

div
.bind("setData",function(e,key,value){ hits[key] += value; })
.bind("setData.foo",function(e,key,value){ hits[key] += value; })
.bind("changeData",logChangeData)
.bind("changeData.foo",logChangeData)
.bind("getData",function(e,key){ gets[key] += 1; })
.bind("getData.foo",function(e,key){ gets[key] += 3; });

@@ -102,19 +114,22 @@ test(".data(String) and .data(String, Object)", function() {
equals( div.data("test.bar"), "overwritten", "Check for unmatched namespace" );
equals( hits.test, 2, "Check triggered setter functions" );
equals( gets.test, 5, "Check triggered getter functions" );
equals( changes.test, 2, "Check sets raise changeData");
equals( changes.value, 2, "Check changeData after data has been set" );

hits.test = 0;
gets.test = 0;
changes.test = 0;
changes.value = null;

div.data("test", 1);
equals( div.data("test"), 1, "Check for original data" );
equals( div.data("test.foo"), 2, "Check for namespaced data" );
equals( div.data("test.bar"), 1, "Check for unmatched namespace" );
equals( hits.test, 1, "Check triggered setter functions" );
equals( gets.test, 5, "Check triggered getter functions" );

hits.test = 0;
gets.test = 0;
equals( changes.test, 1, "Check sets raise changeData" );
equals( changes.value, 1, "Check changeData after data has been set" );

div
.bind("getData",function(e,key){ return key + "root"; })

9 comments on commit 2e10af1

@defkode
Copy link

@defkode defkode commented on 2e10af1 Jul 20, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thats fantastic and useful addition.

@justinbmeyer
Copy link
Contributor

@justinbmeyer justinbmeyer commented on 2e10af1 Jul 26, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm misunderstanding this code on first pass, but does this trigger an event that will walk up the dom everytime someone changes jQuery data? Won't this potentially cause huge performance issues?

@louisremi
Copy link
Contributor

@louisremi louisremi commented on 2e10af1 Jul 27, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would have been perfect as a plugin, considering the potential performance issues. I will no think twice before using .data()

@cowboy
Copy link
Member

@cowboy cowboy commented on 2e10af1 Jul 27, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use the $.data( elem, ... ) syntax instead of $(elem).data( ... ) if you don't want any of the events to fire.

@louisremi
Copy link
Contributor

@louisremi louisremi commented on 2e10af1 Jul 27, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, but I still think it made more sense as a plugin.

@jeresig
Copy link
Member

@jeresig jeresig commented on 2e10af1 Jul 27, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@justin, Irbabe: We've always fired events on the manipulation of .data() (previously just getData/setData and now with the useful addition of changeData). It looks like setData/changeData are bubbling - which should not be the case. I'll change this in a follow-up commit.

@jeresig
Copy link
Member

@jeresig jeresig commented on 2e10af1 Jul 27, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in c4b4df4.

@jupiterjs
Copy link

@jupiterjs jupiterjs commented on 2e10af1 Jul 27, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I knew it was sending events. I was just surprised it was bubbling. I don't think data events should be bubbling by default.

However, I can definitely see a use case for data listeners - plugins that listen high on the dom for data changes and send an Ajax request back to the server -and these would require bubbling data events. But, someone should have to opt-in for this performance penalty.

BTW: this is Justin, l realized I was logged in with my other account.

@louisremi
Copy link
Contributor

@louisremi louisremi commented on 2e10af1 Jul 27, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Fixed in c4b4df4."
Yay!

Please sign in to comment.