thinky icon indicating copy to clipboard operation
thinky copied to clipboard

Flag model instances as 'dirty' when an enumerable property is changed

Open mshick opened this issue 11 years ago • 2 comments

If would be useful if you could set a flag on model instances that told you whether something had changed which you may want to persist to the database. As in, is the model now "dirty."

I imagine the implementation being something like this:

  • Replace enumerable properties (ie, those defined in the schema) with getters and setters
  • When one of those properties is set, immediately update an internal status flag to indicate the entire model is now "dirty"
  • Enable checking via a method like, model.isDirty()
  • Optional: Also store the property or properties that have been modified to make the model "dirty"
  • Optional: Implement a method .set() for setting new properties and giving them the same behavior

mshick avatar May 09 '14 21:05 mshick

I thought a little about that, and implementing something like document.isDirty() is doable, but requires to make a deep copy of the document.

So the question is just about what the default should be? It sounds reasonable to have it on by default, and let people turn it off if they don't want it.

neumino avatar May 21 '14 20:05 neumino

Hm, I'm curious, why do you think the deep copy is required? As I imagine it, you might store the real properties of the document in some hidden internal object (jugglingdb and backbone models both use this approach) and present them on the object in some way.

I'm probably just missing something about the Thinky implementation, but here's some pseudo code for the feature:

new Model(data);
--> Model ctor
function Model(data) {
  this._dirty = false;
  this._dirtyFields = {};
  this._data = data;
  for (var prop in data) {
    Object.define(this, prop, {
      get: function () {
        return this._data[prop];
      },
      set: function (val) {
        this._dirty = true;
        this._dirtyFields[prop];
        this._data[prop] = val;
     }
    );
}
Model.prototype.isDirty = function () {
  return this._dirty;
}
Model.prototype.getDirtyFields = function () {
  return this._dirtyFields;
}
Model.prototype.setSaved = function () {
  // normal setSaved stuff
  this._dirty = false;
  this._dirtyFields = {};
}

Regardless, I'd favor having it on by default since it's of great utility when using a model.

Thanks for considering!

mshick avatar May 21 '14 21:05 mshick