Skip to content

Instantly share code, notes, and snippets.

@trek
Created October 5, 2012 23:15
Show Gist options
  • Save trek/3843009 to your computer and use it in GitHub Desktop.
Save trek/3843009 to your computer and use it in GitHub Desktop.
var modelPrototype = DS.Model.proto(),
modelPrototypeComputedProperties = Em.meta(modelPrototype).descs,
modelConstructorComputedProperties = Em.meta(DS.Model).descs;
var eachEmbeddedObject = function(callback, binding) {
Ember.get(this.constructor, 'embeddedObjects').forEach(function(name, meta) {
callback.call(binding, name, meta);
}, binding);
};
var embeddedObjects = Ember.computed(function(){
var map = Ember.Map.create();
this.eachComputedProperty(function(name, meta) {
if (meta.isEmbedded) {
meta.name = name;
map.set(name, meta);
}
});
return map;
}).cacheable();
/**
@extends Ember.Object
@implements DS.Model#data
DS.Model#setupData
DS.Model#eachAttribute
DS.Model#eachAssociation
DS.Model#materializeAttribute
DS.Model#materializeBelongsTo
DS.Model#id
DS.Model#materializeId
*/
DS.EmbeddedObject = Ember.Object.extend({
data: modelPrototypeComputedProperties.data,
setupData: modelPrototype.setupData,
eachAttribute: modelPrototype.eachAttribute,
eachAssociation: modelPrototype.eachAssociation,
materializeAttribute: modelPrototype.materializeAttribute,
materializeBelongsTo: modelPrototype.materializeBelongsTo,
materializeDataWithSerializer: function(hash, serializer){
this.setupData();
serializer.materializeFromJSON(this, hash);
return this;
},
id: '0',
materializeId: function(){ return '0' },
eachEmbeddedObject: eachEmbeddedObject,
setProperty: function(key, value){
var ownerPropertyName = this.get('_asProperty'),
owner = this.get('owner');
owner.addDirtyFactor(ownerPropertyName);
return value;
},
addDirtyFactor: function(propertyName){
this.get('owner').addDirtyFactor(propertyName);
}
});
DS.EmbeddedObject.reopenClass({
createRecord: DS.Model._create,
attributes: modelConstructorComputedProperties.attributes,
associationsByName: modelConstructorComputedProperties.associationsByName,
embeddedObjects: embeddedObjects
});
DS.Model.reopen({
eachEmbeddedObject: eachEmbeddedObject
});
DS.Model.reopenClass({
embeddedObjects: embeddedObjects
});
DS.Serializer.reopen({
materializeEmbeddedObjects: function(record, hash){
record.eachEmbeddedObject(function(name, attribute) {
this.materializeEmbeddedObject(record, hash, name, attribute.type);
}, this);
},
materializeEmbeddedObject: function(record, hash, name, type){
if (hash == 'loading') { return; }
if (Ember.isArray(hash[name])) {
var value = this._materializeEmbeddedArray(record, hash, name, type);
record._data.attributes[name] = value;
}
},
_materializeEmbeddedArray: function(record, hash, name, type){
return hash[name].map(function(json){
return Ember.get(window, type).create({owner: record, _asProperty: name}).materializeDataWithSerializer(json, this)
}, this);
},
materializeFromJSON: function(record, hash){
this.materializeEmbeddedObjects(record, hash);
return this._super(record, hash);
}
});
DS.embedded = function(type, options){
var meta = { type: type, isEmbedded: true, options: options, kind: 'nestedArray' };
return Ember.computed(function(key, value) {
var owner = this;
var related = Ember.ArrayProxy.create({
owner: owner,
content: function(){
return owner._data.attributes[key] || [];
}.property(),
replace: function(idx, amt, objects) {
this._super(idx, amt, objects);
owner.addDirtyFactor(key);
return this;
}
});
return related;
}).property('data').cacheable().meta(meta);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment