views:

176

answers:

3

ASP.NET AJAX 4 recently added the ability to track changes to ADO.NET Data Services objects on the client side. That got me wondering what other change tracking JavaScript libraries exist. Has anyone seen any, or are you using any?

EDIT: Just to clarify what I mean by "change tracking": the new version of ASP.NET AJAX allows you to retrieve a JavaScript object, make changes to it on the client, then send only those changes back to the server.

A: 

Comet could potentially be used for change tracking by pushing changes to the client (as opposed to polling the server for them):

Comet

cballou
+2  A: 

I don't know of a framework, but using prototypal inheritance and hasOwnProperty, it's almost trivial to roll your own.

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

var objectToTrack = getFromServer();
var objectToModify = object(objectToTrack);

edit(objectToModify); // let the user edit it...

var changes = {};
for(var p in objectToModify) {
   if(objectToModify.hasOwnProperty(p)) {
     changes[p] = objectToModify[p];
   }
}
sendChanges(changes);

One caveat: prototypal inheritance is (for lack of a better word) "shallow". If the object has any Array or Object properties, then modifying them will modify the original, which may not be what you want. They also wont be picked up by hasOwnProperty. To remedy this, your editing logic needs to be aware of when a sub-object or array property is edited by the user and track it individually, using the same technique. e.g.,

var foo = { foo: [1,2,3], bar: 0, baz: { hello: "world!" } };
var bar = object(foo);
bar.foo[1] = 3; 
// foo.foo[1] is now also 3, but bar.hasOwnProperty('foo') returns false
bar.bar = 123; // foo is unchanged, bar.hasOwnProperty('bar') returns true

function editFooArray(index,value) {
   if(!bar.hasOwnProperty('foo')) {
     // copies the array, bar now hasOwnProperty('foo')
     bar.foo = bar.foo.slice(0); 
   }
   bar.foo[index] = value;
}

function editBazObj(property,value) {
   if(!bar.hasOwnProperty('baz')) {
     bar.baz = object(foo.baz);
   }
   bar.baz[property] = value;
}
noah
Wow! I bow to your JavaScript wizardry. :-)
GuyBehindtheGuy
Points awarded for your effort, Noah. I do wish I'd found out about a new framework, though.
GuyBehindtheGuy
+1  A: 

If by only those changes, you mean field level changes, then I don't know of anything that works that way out of the box. For the object/record level, every framework with a defined data api (dojo, yui 2/3, ext, sproutcore, activejs) provides something to allow you to get the data back to the server when an object in the store changes.

Sproutcore goes the extra mile of tracking clean/dirty records in the store for batch upload. That plus the general Key-Value Observation utilities should make tweaking it to support field-level changes should be trivial if that's what you're looking for.

Karl Guertin