Is there a change-tracking framework for JavaScript?

javascript

Solution

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;
}

Problem

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.

Original source