Skip to content

Instantly share code, notes, and snippets.

@endash
Created March 31, 2014 22:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save endash/9904020 to your computer and use it in GitHub Desktop.
Save endash/9904020 to your computer and use it in GitHub Desktop.
ModelProxy = Ember.Object.extend(Ember.Validations.Mixin, Ember.ActionHandler, {
init: function() {
this.props = {};
this._super.apply(this, arguments);
},
autosave: false,
content: null,
_contentDidChange: Ember.observer('content', function() {
Ember.assert("Can't set ModelProxy's content to itself", this.get('content') !== this);
}),
isInvalidOrSaving: Ember.computed.or('isInvalid', 'isSaving'),
isDirty: Ember.computed(function (key, value) {
if (arguments.length === 2) return value;
var content = this.get('content');
if (!content) return false;
if (!this.props) return false;
return !!(Ember.keys(this.props).find(function (key) {
return this.props[key] != content.get(key);
}, this));
}),
isClean: Ember.computed.not('isDirty'),
willWatchProperty: function (key) {
var contentKey = 'content.' + key;
addBeforeObserver(this, contentKey, null, contentPropertyWillChange);
addObserver(this, contentKey, null, contentPropertyDidChange);
(this.watchedProps || (this.watchedProps = [])).addObject(key)
},
didUnwatchProperty: function (key, keepProp) {
var contentKey = 'content.' + key;
removeBeforeObserver(this, contentKey, null, contentPropertyWillChange);
removeObserver(this, contentKey, null, contentPropertyDidChange);
if (!keepProp) { this.watchedProps.removeObject(key); }
},
unknownProperty: function (key) {
var content = get(this, 'content'), props = this.props || {};
if (props[key] !== undefined) {
return props[key];
} else if (content) {
return get(content, key);
}
},
setUnknownProperty: function (key, value) {
var m = meta(this);
if (m.proto === this) {
// if marked as prototype then just defineProperty
// rather than delegate
defineProperty(this, key, null, value);
return value;
}
if (!this.props) this.props = {}
if (this.watchedProps && this.watchedProps.contains(key)) {
this.didUnwatchProperty(key, true); // we have our own value
}
this.props[key] = value;
this.notifyPropertyChange('isDirty');
this.notifyPropertyChange(key);
if (this.get('autosave')) this.debounceSave();
return value;
},
flush: function () {
var content = get(this, 'content');
Ember.assert(fmt("Cannot flush changes to the 'content' property of form proxy %@: its 'content' is undefined.", [this]), content);
// content.setProperties(this.props)
Ember.keys(this.props).forEach(function (key) {
if (this.watchedProps.contains(key)) { this.willWatchProperty(key); }
content.set(key, this.props[key]);
}, this);
this.props = {};
},
debounceSave: function () {
Ember.run.debounce(this, this._debounceSave, 1000);
},
_debounceSave: function () {
var content = this.get('content');
if (content.get('isSaving')) {
this.debounceSave();
} else if (this.get('isDirty')){
this.save();
}
},
save: function () {
if (this.get('isValid')) {
this.get('content').save();
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment