Skip to content

Instantly share code, notes, and snippets.

@lukemelia
Last active May 5, 2016 20:47
Show Gist options
  • Star 20 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lukemelia/5632776 to your computer and use it in GitHub Desktop.
Save lukemelia/5632776 to your computer and use it in GitHub Desktop.
Buffered Proxy, extracted from Yapp codebase
var empty, get, set,
__hasProp = {}.hasOwnProperty;
get = Ember.get;
set = Ember.set;
empty = function(obj) {
var key;
for (key in obj) {
if (!__hasProp.call(obj, key)) continue;
return false;
}
return true;
};
Yapp.BufferedProxyMixin = Ember.Mixin.create({
buffer: null,
hasBufferedChanges: false,
unknownProperty: function(key) {
var buffer;
buffer = this.buffer;
if (!(buffer != null ? buffer.hasOwnProperty(key) : void 0)) {
return this._super(key);
}
return buffer[key];
},
setUnknownProperty: function(key, value) {
var buffer, content, current, previous, _ref;
buffer = (_ref = this.buffer) != null ? _ref : this.buffer = {};
content = this.get("content");
if (content != null) {
current = get(content, key);
}
previous = buffer.hasOwnProperty(key) ? buffer[key] : current;
if (previous === value) {
return;
}
this.propertyWillChange(key);
if (current === value) {
delete buffer[key];
if (empty(buffer)) {
this.set("hasBufferedChanges", false);
}
} else {
buffer[key] = value;
this.set("hasBufferedChanges", true);
}
this.propertyDidChange(key);
return value;
},
applyBufferedChanges: function() {
var buffer, content, key;
buffer = this.buffer;
content = this.get("content");
for (key in buffer) {
if (!__hasProp.call(buffer, key)) continue;
set(content, key, buffer[key]);
}
this.buffer = {};
this.set("hasBufferedChanges", false);
return this;
},
discardBufferedChanges: function() {
var buffer, content, key;
buffer = this.buffer;
content = this.get("content");
for (key in buffer) {
if (!__hasProp.call(buffer, key)) continue;
this.propertyWillChange(key);
delete buffer[key];
this.propertyDidChange(key);
}
this.set("hasBufferedChanges", false);
return this;
}
});
Yapp.BufferedProxy = Em.ObjectProxy.extend(Yapp.BufferedProxyMixin);
@taras
Copy link

taras commented Oct 12, 2013

@lukemelia, do you guys use this code regularly? Is this the latest version of it?

@stefanpenner
Copy link

We use this regularly. It is near to what we use in production.

but we should likely extract it as a standalone repo.

@sheldonbaker
Copy link

This is really cool. There's one caveat (related more to ember-data of course) I reported in an issue. How do you guys work around this (if at all)?

actions:
  save: ->
    content = @get('content')
    @applyBufferedChanges()

    content.save().then ->
      // sweet
    , ->
      // uh oh - now the record has our changes applied but they aren't valid
      // we could rollback those changes, but the record will have gone from
      // 'My Title' to 'My New Title' and back to 'My Title' - which would be odd for the user

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment