1696 lines
43 KiB
JavaScript
1696 lines
43 KiB
JavaScript
(function() {
|
|
|
|
var VERSION = '0.0.10';
|
|
|
|
if (Ember.libraries) {
|
|
Ember.libraries.register('Ember Model', VERSION);
|
|
}
|
|
|
|
|
|
})();
|
|
|
|
(function() {
|
|
|
|
function mustImplement(message) {
|
|
var fn = function() {
|
|
var className = this.constructor.toString();
|
|
|
|
throw new Error(message.replace('{{className}}', className));
|
|
};
|
|
fn.isUnimplemented = true;
|
|
return fn;
|
|
}
|
|
|
|
Ember.Adapter = Ember.Object.extend({
|
|
find: mustImplement('{{className}} must implement find'),
|
|
findQuery: mustImplement('{{className}} must implement findQuery'),
|
|
findMany: mustImplement('{{className}} must implement findMany'),
|
|
findAll: mustImplement('{{className}} must implement findAll'),
|
|
createRecord: mustImplement('{{className}} must implement createRecord'),
|
|
saveRecord: mustImplement('{{className}} must implement saveRecord'),
|
|
deleteRecord: mustImplement('{{className}} must implement deleteRecord'),
|
|
|
|
load: function(record, id, data) {
|
|
record.load(id, data);
|
|
}
|
|
});
|
|
|
|
|
|
})();
|
|
|
|
(function() {
|
|
|
|
var get = Ember.get;
|
|
|
|
Ember.FixtureAdapter = Ember.Adapter.extend({
|
|
_findData: function(klass, id) {
|
|
var fixtures = klass.FIXTURES,
|
|
idAsString = id.toString(),
|
|
primaryKey = get(klass, 'primaryKey'),
|
|
data = Ember.A(fixtures).find(function(el) { return (el[primaryKey]).toString() === idAsString; });
|
|
|
|
return data;
|
|
},
|
|
|
|
find: function(record, id) {
|
|
var data = this._findData(record.constructor, id);
|
|
|
|
return new Ember.RSVP.Promise(function(resolve, reject) {
|
|
Ember.run.later(this, function() {
|
|
Ember.run(record, record.load, id, data);
|
|
resolve(record);
|
|
}, 0);
|
|
});
|
|
},
|
|
|
|
findMany: function(klass, records, ids) {
|
|
var fixtures = klass.FIXTURES,
|
|
requestedData = [];
|
|
|
|
for (var i = 0, l = ids.length; i < l; i++) {
|
|
requestedData.push(this._findData(klass, ids[i]));
|
|
}
|
|
|
|
return new Ember.RSVP.Promise(function(resolve, reject) {
|
|
Ember.run.later(this, function() {
|
|
Ember.run(records, records.load, klass, requestedData);
|
|
resolve(records);
|
|
}, 0);
|
|
});
|
|
},
|
|
|
|
findAll: function(klass, records) {
|
|
var fixtures = klass.FIXTURES;
|
|
|
|
return new Ember.RSVP.Promise(function(resolve, reject) {
|
|
Ember.run.later(this, function() {
|
|
Ember.run(records, records.load, klass, fixtures);
|
|
resolve(records);
|
|
}, 0);
|
|
});
|
|
},
|
|
|
|
createRecord: function(record) {
|
|
var klass = record.constructor,
|
|
fixtures = klass.FIXTURES;
|
|
|
|
return new Ember.RSVP.Promise(function(resolve, reject) {
|
|
Ember.run.later(this, function() {
|
|
fixtures.push(klass.findFromCacheOrLoad(record.toJSON()));
|
|
record.didCreateRecord();
|
|
resolve(record);
|
|
}, 0);
|
|
});
|
|
},
|
|
|
|
saveRecord: function(record) {
|
|
return new Ember.RSVP.Promise(function(resolve, reject) {
|
|
Ember.run.later(this, function() {
|
|
record.didSaveRecord();
|
|
resolve(record);
|
|
}, 0);
|
|
});
|
|
},
|
|
|
|
deleteRecord: function(record) {
|
|
return new Ember.RSVP.Promise(function(resolve, reject) {
|
|
Ember.run.later(this, function() {
|
|
record.didDeleteRecord();
|
|
resolve(record);
|
|
}, 0);
|
|
});
|
|
}
|
|
});
|
|
|
|
|
|
})();
|
|
|
|
(function() {
|
|
|
|
var get = Ember.get,
|
|
set = Ember.set;
|
|
|
|
Ember.RecordArray = Ember.ArrayProxy.extend(Ember.Evented, {
|
|
isLoaded: false,
|
|
isLoading: Ember.computed.not('isLoaded'),
|
|
|
|
load: function(klass, data) {
|
|
set(this, 'content', this.materializeData(klass, data));
|
|
this.notifyLoaded();
|
|
},
|
|
|
|
loadForFindMany: function(klass) {
|
|
var content = get(this, '_ids').map(function(id) { return klass.cachedRecordForId(id); });
|
|
set(this, 'content', Ember.A(content));
|
|
this.notifyLoaded();
|
|
},
|
|
|
|
notifyLoaded: function() {
|
|
set(this, 'isLoaded', true);
|
|
this.trigger('didLoad');
|
|
},
|
|
|
|
materializeData: function(klass, data) {
|
|
return Ember.A(data.map(function(el) {
|
|
return klass.findFromCacheOrLoad(el); // FIXME
|
|
}));
|
|
},
|
|
|
|
reload: function() {
|
|
var modelClass = this.get('modelClass'),
|
|
self = this,
|
|
promises;
|
|
|
|
set(this, 'isLoaded', false);
|
|
if (modelClass._findAllRecordArray === this) {
|
|
return modelClass.adapter.findAll(modelClass, this);
|
|
} else if (this._query) {
|
|
return modelClass.adapter.findQuery(modelClass, this, this._query);
|
|
} else {
|
|
promises = this.map(function(record) {
|
|
return record.reload();
|
|
});
|
|
return Ember.RSVP.all(promises).then(function(data) {
|
|
self.notifyLoaded();
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
})();
|
|
|
|
(function() {
|
|
|
|
var get = Ember.get;
|
|
|
|
Ember.FilteredRecordArray = Ember.RecordArray.extend({
|
|
init: function() {
|
|
if (!get(this, 'modelClass')) {
|
|
throw new Error('FilteredRecordArrays must be created with a modelClass');
|
|
}
|
|
if (!get(this, 'filterFunction')) {
|
|
throw new Error('FilteredRecordArrays must be created with a filterFunction');
|
|
}
|
|
if (!get(this, 'filterProperties')) {
|
|
throw new Error('FilteredRecordArrays must be created with filterProperties');
|
|
}
|
|
|
|
var modelClass = get(this, 'modelClass');
|
|
modelClass.registerRecordArray(this);
|
|
|
|
this.registerObservers();
|
|
this.updateFilter();
|
|
|
|
this._super();
|
|
},
|
|
|
|
updateFilter: function() {
|
|
var self = this,
|
|
results = [];
|
|
get(this, 'modelClass').forEachCachedRecord(function(record) {
|
|
if (self.filterFunction(record)) {
|
|
results.push(record);
|
|
}
|
|
});
|
|
this.set('content', Ember.A(results));
|
|
},
|
|
|
|
updateFilterForRecord: function(record) {
|
|
var results = get(this, 'content'),
|
|
filterMatches = this.filterFunction(record);
|
|
if (filterMatches && !results.contains(record)) {
|
|
results.pushObject(record);
|
|
} else if(!filterMatches) {
|
|
results.removeObject(record);
|
|
}
|
|
},
|
|
|
|
registerObservers: function() {
|
|
var self = this;
|
|
get(this, 'modelClass').forEachCachedRecord(function(record) {
|
|
self.registerObserversOnRecord(record);
|
|
});
|
|
},
|
|
|
|
registerObserversOnRecord: function(record) {
|
|
var self = this,
|
|
filterProperties = get(this, 'filterProperties');
|
|
|
|
for (var i = 0, l = get(filterProperties, 'length'); i < l; i++) {
|
|
record.addObserver(filterProperties[i], self, 'updateFilterForRecord');
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
})();
|
|
|
|
(function() {
|
|
|
|
var get = Ember.get, set = Ember.set;
|
|
|
|
Ember.ManyArray = Ember.RecordArray.extend({
|
|
_records: null,
|
|
originalContent: [],
|
|
|
|
isDirty: function() {
|
|
var originalContent = get(this, 'originalContent'),
|
|
originalContentLength = get(originalContent, 'length'),
|
|
content = get(this, 'content'),
|
|
contentLength = get(content, 'length');
|
|
|
|
if (originalContentLength !== contentLength) { return true; }
|
|
|
|
var isDirty = false;
|
|
|
|
for (var i = 0, l = contentLength; i < l; i++) {
|
|
if (!originalContent.contains(content[i])) {
|
|
isDirty = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return isDirty;
|
|
}.property('content.[]', 'originalContent'),
|
|
|
|
objectAtContent: function(idx) {
|
|
var content = get(this, 'content');
|
|
|
|
if (!content.length) { return; }
|
|
|
|
return this.materializeRecord(idx);
|
|
},
|
|
|
|
save: function() {
|
|
// TODO: loop over dirty records only
|
|
return Ember.RSVP.all(this.map(function(record) {
|
|
return record.save();
|
|
}));
|
|
},
|
|
|
|
replaceContent: function(index, removed, added) {
|
|
added = Ember.EnumerableUtils.map(added, function(record) {
|
|
return record._reference;
|
|
}, this);
|
|
|
|
this._super(index, removed, added);
|
|
},
|
|
|
|
_contentWillChange: function() {
|
|
var content = get(this, 'content');
|
|
if (content) {
|
|
content.removeArrayObserver(this);
|
|
this._setupOriginalContent(content);
|
|
}
|
|
}.observesBefore('content'),
|
|
|
|
_contentDidChange: function() {
|
|
var content = get(this, 'content');
|
|
if (content) {
|
|
content.addArrayObserver(this);
|
|
this.arrayDidChange(content, 0, 0, get(content, 'length'));
|
|
}
|
|
}.observes('content'),
|
|
|
|
arrayWillChange: function(item, idx, removedCnt, addedCnt) {},
|
|
|
|
arrayDidChange: function(item, idx, removedCnt, addedCnt) {
|
|
var parent = get(this, 'parent'), relationshipKey = get(this, 'relationshipKey'),
|
|
isDirty = get(this, 'isDirty');
|
|
|
|
if (isDirty) {
|
|
parent._relationshipBecameDirty(relationshipKey);
|
|
} else {
|
|
parent._relationshipBecameClean(relationshipKey);
|
|
}
|
|
},
|
|
|
|
_setupOriginalContent: function(content) {
|
|
content = content || get(this, 'content');
|
|
if (content) {
|
|
set(this, 'originalContent', content.slice());
|
|
}
|
|
},
|
|
|
|
init: function() {
|
|
this._super();
|
|
this._setupOriginalContent();
|
|
this._contentDidChange();
|
|
}
|
|
});
|
|
|
|
Ember.HasManyArray = Ember.ManyArray.extend({
|
|
materializeRecord: function(idx) {
|
|
var klass = get(this, 'modelClass'),
|
|
content = get(this, 'content'),
|
|
reference = content.objectAt(idx),
|
|
record;
|
|
|
|
if (reference.record) {
|
|
record = reference.record;
|
|
} else {
|
|
record = klass.find(reference.id);
|
|
}
|
|
|
|
return record;
|
|
},
|
|
|
|
toJSON: function() {
|
|
var ids = [], content = this.get('content');
|
|
|
|
content.forEach(function(reference) {
|
|
if (reference.id) {
|
|
ids.push(reference.id);
|
|
}
|
|
});
|
|
|
|
return ids;
|
|
}
|
|
});
|
|
|
|
Ember.EmbeddedHasManyArray = Ember.ManyArray.extend({
|
|
create: function(attrs) {
|
|
var klass = get(this, 'modelClass'),
|
|
record = klass.create(attrs);
|
|
|
|
this.pushObject(record);
|
|
|
|
return record; // FIXME: inject parent's id
|
|
},
|
|
|
|
materializeRecord: function(idx) {
|
|
var klass = get(this, 'modelClass'),
|
|
primaryKey = get(klass, 'primaryKey'),
|
|
content = get(this, 'content'),
|
|
reference = content.objectAt(idx),
|
|
attrs = reference.data;
|
|
|
|
if (reference.record) {
|
|
return reference.record;
|
|
} else {
|
|
var record = klass.create({ _reference: reference });
|
|
reference.record = record;
|
|
if (attrs) {
|
|
record.load(attrs[primaryKey], attrs);
|
|
}
|
|
return record;
|
|
}
|
|
},
|
|
|
|
toJSON: function() {
|
|
return this.map(function(record) {
|
|
return record.toJSON();
|
|
});
|
|
}
|
|
});
|
|
|
|
|
|
})();
|
|
|
|
(function() {
|
|
|
|
var get = Ember.get,
|
|
set = Ember.set,
|
|
setProperties = Ember.setProperties,
|
|
meta = Ember.meta,
|
|
underscore = Ember.String.underscore;
|
|
|
|
function contains(array, element) {
|
|
for (var i = 0, l = array.length; i < l; i++) {
|
|
if (array[i] === element) { return true; }
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function concatUnique(toArray, fromArray) {
|
|
var e;
|
|
for (var i = 0, l = fromArray.length; i < l; i++) {
|
|
e = fromArray[i];
|
|
if (!contains(toArray, e)) { toArray.push(e); }
|
|
}
|
|
return toArray;
|
|
}
|
|
|
|
function hasCachedValue(object, key) {
|
|
var objectMeta = meta(object, false);
|
|
if (objectMeta) {
|
|
return key in objectMeta.cache;
|
|
}
|
|
}
|
|
|
|
Ember.run.queues.push('data');
|
|
|
|
Ember.Model = Ember.Object.extend(Ember.Evented, {
|
|
isLoaded: true,
|
|
isLoading: Ember.computed.not('isLoaded'),
|
|
isNew: true,
|
|
isDeleted: false,
|
|
_dirtyAttributes: null,
|
|
|
|
/**
|
|
Called when attribute is accessed.
|
|
|
|
@method getAttr
|
|
@param key {String} key which is being accessed
|
|
@param value {Object} value, which will be returned from getter by default
|
|
*/
|
|
getAttr: function(key, value) {
|
|
return value;
|
|
},
|
|
|
|
isDirty: function() {
|
|
var dirtyAttributes = get(this, '_dirtyAttributes');
|
|
return dirtyAttributes && dirtyAttributes.length !== 0 || false;
|
|
}.property('_dirtyAttributes.length'),
|
|
|
|
_relationshipBecameDirty: function(name) {
|
|
var dirtyAttributes = get(this, '_dirtyAttributes');
|
|
if (!dirtyAttributes.contains(name)) { dirtyAttributes.pushObject(name); }
|
|
},
|
|
|
|
_relationshipBecameClean: function(name) {
|
|
var dirtyAttributes = get(this, '_dirtyAttributes');
|
|
dirtyAttributes.removeObject(name);
|
|
},
|
|
|
|
dataKey: function(key) {
|
|
var camelizeKeys = get(this.constructor, 'camelizeKeys');
|
|
var meta = this.constructor.metaForProperty(key);
|
|
if (meta.options && meta.options.key) {
|
|
return camelizeKeys ? underscore(meta.options.key) : meta.options.key;
|
|
}
|
|
return camelizeKeys ? underscore(key) : key;
|
|
},
|
|
|
|
init: function() {
|
|
this._createReference();
|
|
if (!this._dirtyAttributes) {
|
|
set(this, '_dirtyAttributes', []);
|
|
}
|
|
this._super();
|
|
},
|
|
|
|
_createReference: function() {
|
|
var reference = this._reference,
|
|
id = this.getPrimaryKey();
|
|
|
|
if (!reference) {
|
|
reference = this.constructor._getOrCreateReferenceForId(id);
|
|
reference.record = this;
|
|
this._reference = reference;
|
|
} else if (reference.id !== id) {
|
|
reference.id = id;
|
|
this.constructor._cacheReference(reference);
|
|
}
|
|
|
|
if (!reference.id) {
|
|
reference.id = id;
|
|
}
|
|
|
|
return reference;
|
|
},
|
|
|
|
getPrimaryKey: function() {
|
|
return get(this, get(this.constructor, 'primaryKey'));
|
|
},
|
|
|
|
load: function(id, hash) {
|
|
var data = {};
|
|
data[get(this.constructor, 'primaryKey')] = id;
|
|
set(this, '_data', Ember.merge(data, hash));
|
|
|
|
// eagerly load embedded data
|
|
var relationships = this.constructor._relationships || [], meta = Ember.meta(this), relationshipKey, relationship, relationshipMeta, relationshipData, relationshipType;
|
|
for (var i = 0, l = relationships.length; i < l; i++) {
|
|
relationshipKey = relationships[i];
|
|
relationship = meta.descs[relationshipKey];
|
|
relationshipMeta = relationship.meta();
|
|
|
|
if (relationshipMeta.options.embedded) {
|
|
relationshipType = relationshipMeta.type;
|
|
if (typeof relationshipType === "string") {
|
|
relationshipType = Ember.get(Ember.lookup, relationshipType);
|
|
}
|
|
|
|
relationshipData = data[relationshipKey];
|
|
if (relationshipData) {
|
|
relationshipType.load(relationshipData);
|
|
}
|
|
}
|
|
}
|
|
|
|
set(this, 'isLoaded', true);
|
|
set(this, 'isNew', false);
|
|
this._createReference();
|
|
this.trigger('didLoad');
|
|
},
|
|
|
|
didDefineProperty: function(proto, key, value) {
|
|
if (value instanceof Ember.Descriptor) {
|
|
var meta = value.meta();
|
|
var klass = proto.constructor;
|
|
|
|
if (meta.isAttribute) {
|
|
if (!klass._attributes) { klass._attributes = []; }
|
|
klass._attributes.push(key);
|
|
} else if (meta.isRelationship) {
|
|
if (!klass._relationships) { klass._relationships = []; }
|
|
klass._relationships.push(key);
|
|
meta.relationshipKey = key;
|
|
}
|
|
}
|
|
},
|
|
|
|
serializeHasMany: function(key, meta) {
|
|
return this.get(key).toJSON();
|
|
},
|
|
|
|
serializeBelongsTo: function(key, meta) {
|
|
if (meta.options.embedded) {
|
|
var record = this.get(key);
|
|
return record ? record.toJSON() : null;
|
|
} else {
|
|
var primaryKey = get(meta.getType(), 'primaryKey');
|
|
return this.get(key + '.' + primaryKey);
|
|
}
|
|
},
|
|
|
|
toJSON: function() {
|
|
var key, meta,
|
|
json = {},
|
|
attributes = this.constructor.getAttributes(),
|
|
relationships = this.constructor.getRelationships(),
|
|
properties = attributes ? this.getProperties(attributes) : {},
|
|
rootKey = get(this.constructor, 'rootKey');
|
|
|
|
for (key in properties) {
|
|
meta = this.constructor.metaForProperty(key);
|
|
if (meta.type && meta.type.serialize) {
|
|
json[this.dataKey(key)] = meta.type.serialize(properties[key]);
|
|
} else if (meta.type && Ember.Model.dataTypes[meta.type]) {
|
|
json[this.dataKey(key)] = Ember.Model.dataTypes[meta.type].serialize(properties[key]);
|
|
} else {
|
|
json[this.dataKey(key)] = properties[key];
|
|
}
|
|
}
|
|
|
|
if (relationships) {
|
|
var data, relationshipKey;
|
|
|
|
for(var i = 0; i < relationships.length; i++) {
|
|
key = relationships[i];
|
|
meta = this.constructor.metaForProperty(key);
|
|
relationshipKey = meta.options.key || key;
|
|
|
|
if (meta.kind === 'belongsTo') {
|
|
data = this.serializeBelongsTo(key, meta);
|
|
} else {
|
|
data = this.serializeHasMany(key, meta);
|
|
}
|
|
|
|
json[relationshipKey] = data;
|
|
|
|
}
|
|
}
|
|
|
|
if (rootKey) {
|
|
var jsonRoot = {};
|
|
jsonRoot[rootKey] = json;
|
|
return jsonRoot;
|
|
} else {
|
|
return json;
|
|
}
|
|
},
|
|
|
|
save: function() {
|
|
var adapter = this.constructor.adapter;
|
|
set(this, 'isSaving', true);
|
|
if (get(this, 'isNew')) {
|
|
return adapter.createRecord(this);
|
|
} else if (get(this, 'isDirty')) {
|
|
return adapter.saveRecord(this);
|
|
} else { // noop, return a resolved promise
|
|
var self = this,
|
|
promise = new Ember.RSVP.Promise(function(resolve, reject) {
|
|
resolve(self);
|
|
});
|
|
set(this, 'isSaving', false);
|
|
return promise;
|
|
}
|
|
},
|
|
|
|
reload: function() {
|
|
this.getWithDefault('_dirtyAttributes', []).clear();
|
|
return this.constructor.reload(this.get(get(this.constructor, 'primaryKey')));
|
|
},
|
|
|
|
revert: function() {
|
|
this.getWithDefault('_dirtyAttributes', []).clear();
|
|
this.notifyPropertyChange('_data');
|
|
},
|
|
|
|
didCreateRecord: function() {
|
|
var primaryKey = get(this.constructor, 'primaryKey'),
|
|
id = get(this, primaryKey);
|
|
|
|
set(this, 'isNew', false);
|
|
|
|
set(this, '_dirtyAttributes', []);
|
|
this.constructor.addToRecordArrays(this);
|
|
this.trigger('didCreateRecord');
|
|
this.didSaveRecord();
|
|
},
|
|
|
|
didSaveRecord: function() {
|
|
set(this, 'isSaving', false);
|
|
this.trigger('didSaveRecord');
|
|
if (this.get('isDirty')) { this._copyDirtyAttributesToData(); }
|
|
},
|
|
|
|
deleteRecord: function() {
|
|
return this.constructor.adapter.deleteRecord(this);
|
|
},
|
|
|
|
didDeleteRecord: function() {
|
|
this.constructor.removeFromRecordArrays(this);
|
|
set(this, 'isDeleted', true);
|
|
this.trigger('didDeleteRecord');
|
|
},
|
|
|
|
_copyDirtyAttributesToData: function() {
|
|
if (!this._dirtyAttributes) { return; }
|
|
var dirtyAttributes = this._dirtyAttributes,
|
|
data = get(this, '_data'),
|
|
key;
|
|
|
|
if (!data) {
|
|
data = {};
|
|
set(this, '_data', data);
|
|
}
|
|
for (var i = 0, l = dirtyAttributes.length; i < l; i++) {
|
|
// TODO: merge Object.create'd object into prototype
|
|
key = dirtyAttributes[i];
|
|
data[this.dataKey(key)] = this.cacheFor(key);
|
|
}
|
|
set(this, '_dirtyAttributes', []);
|
|
},
|
|
|
|
dataDidChange: Ember.observer(function() {
|
|
this._reloadHasManys();
|
|
}, '_data'),
|
|
|
|
_registerHasManyArray: function(array) {
|
|
if (!this._hasManyArrays) { this._hasManyArrays = Ember.A([]); }
|
|
|
|
this._hasManyArrays.pushObject(array);
|
|
},
|
|
|
|
_reloadHasManys: function() {
|
|
if (!this._hasManyArrays) { return; }
|
|
var i, j;
|
|
for (i = 0; i < this._hasManyArrays.length; i++) {
|
|
var array = this._hasManyArrays[i],
|
|
hasManyContent = this._getHasManyContent(get(array, 'key'), get(array, 'modelClass'), get(array, 'embedded'));
|
|
for (j = 0; j < array.get('length'); j++) {
|
|
if (array.objectAt(j).get('isNew')) {
|
|
hasManyContent.addObject(array.objectAt(j)._reference);
|
|
}
|
|
}
|
|
set(array, 'content', hasManyContent);
|
|
}
|
|
},
|
|
|
|
_getHasManyContent: function(key, type, embedded) {
|
|
var content = get(this, '_data.' + key);
|
|
|
|
if (content) {
|
|
var mapFunction, primaryKey, reference;
|
|
if (embedded) {
|
|
primaryKey = get(type, 'primaryKey');
|
|
mapFunction = function(attrs) {
|
|
reference = type._getOrCreateReferenceForId(attrs[primaryKey]);
|
|
reference.data = attrs;
|
|
return reference;
|
|
};
|
|
} else {
|
|
mapFunction = function(id) { return type._getOrCreateReferenceForId(id); };
|
|
}
|
|
content = Ember.EnumerableUtils.map(content, mapFunction);
|
|
}
|
|
|
|
return Ember.A(content || []);
|
|
}
|
|
});
|
|
|
|
Ember.Model.reopenClass({
|
|
primaryKey: 'id',
|
|
|
|
adapter: Ember.Adapter.create(),
|
|
|
|
_clientIdCounter: 1,
|
|
|
|
getAttributes: function() {
|
|
this.proto(); // force class "compilation" if it hasn't been done.
|
|
var attributes = this._attributes || [];
|
|
if (typeof this.superclass.getAttributes === 'function') {
|
|
attributes = this.superclass.getAttributes().concat(attributes);
|
|
}
|
|
return attributes;
|
|
},
|
|
|
|
getRelationships: function() {
|
|
this.proto(); // force class "compilation" if it hasn't been done.
|
|
var relationships = this._relationships || [];
|
|
if (typeof this.superclass.getRelationships === 'function') {
|
|
relationships = this.superclass.getRelationships().concat(relationships);
|
|
}
|
|
return relationships;
|
|
},
|
|
|
|
fetch: function(id) {
|
|
if (!arguments.length) {
|
|
return this._findFetchAll(true);
|
|
} else if (Ember.isArray(id)) {
|
|
return this._findFetchMany(id, true);
|
|
} else if (typeof id === 'object') {
|
|
return this._findFetchQuery(id, true);
|
|
} else {
|
|
return this._findFetchById(id, true);
|
|
}
|
|
},
|
|
|
|
find: function(id) {
|
|
if (!arguments.length) {
|
|
return this._findFetchAll(false);
|
|
} else if (Ember.isArray(id)) {
|
|
return this._findFetchMany(id, false);
|
|
} else if (typeof id === 'object') {
|
|
return this._findFetchQuery(id, false);
|
|
} else {
|
|
return this._findFetchById(id, false);
|
|
}
|
|
},
|
|
|
|
findQuery: function(params) {
|
|
return this._findFetchQuery(params, false);
|
|
},
|
|
|
|
fetchQuery: function(params) {
|
|
return this._findFetchQuery(params, true);
|
|
},
|
|
|
|
_findFetchQuery: function(params, isFetch) {
|
|
var records = Ember.RecordArray.create({modelClass: this, _query: params});
|
|
|
|
var promise = this.adapter.findQuery(this, records, params);
|
|
|
|
return isFetch ? promise : records;
|
|
},
|
|
|
|
findMany: function(ids) {
|
|
return this._findFetchMany(ids, false);
|
|
},
|
|
|
|
fetchMany: function(ids) {
|
|
return this._findFetchMany(ids, true);
|
|
},
|
|
|
|
_findFetchMany: function(ids, isFetch) {
|
|
Ember.assert("findFetchMany requires an array", Ember.isArray(ids));
|
|
|
|
var records = Ember.RecordArray.create({_ids: ids, modelClass: this}),
|
|
deferred;
|
|
|
|
if (!this.recordArrays) { this.recordArrays = []; }
|
|
this.recordArrays.push(records);
|
|
|
|
if (this._currentBatchIds) {
|
|
concatUnique(this._currentBatchIds, ids);
|
|
this._currentBatchRecordArrays.push(records);
|
|
} else {
|
|
this._currentBatchIds = concatUnique([], ids);
|
|
this._currentBatchRecordArrays = [records];
|
|
}
|
|
|
|
if (isFetch) {
|
|
deferred = Ember.Deferred.create();
|
|
Ember.set(deferred, 'resolveWith', records);
|
|
|
|
if (!this._currentBatchDeferreds) { this._currentBatchDeferreds = []; }
|
|
this._currentBatchDeferreds.push(deferred);
|
|
}
|
|
|
|
Ember.run.scheduleOnce('data', this, this._executeBatch);
|
|
|
|
return isFetch ? deferred : records;
|
|
},
|
|
|
|
findAll: function() {
|
|
return this._findFetchAll(false);
|
|
},
|
|
|
|
fetchAll: function() {
|
|
return this._findFetchAll(true);
|
|
},
|
|
|
|
_findFetchAll: function(isFetch) {
|
|
var self = this;
|
|
|
|
if (this._findAllRecordArray) {
|
|
if (isFetch) {
|
|
return new Ember.RSVP.Promise(function(resolve) {
|
|
resolve(self._findAllRecordArray);
|
|
});
|
|
} else {
|
|
return this._findAllRecordArray;
|
|
}
|
|
}
|
|
|
|
var records = this._findAllRecordArray = Ember.RecordArray.create({modelClass: this});
|
|
|
|
var promise = this.adapter.findAll(this, records);
|
|
|
|
// Remove the cached record array if the promise is rejected
|
|
if (promise.then) {
|
|
promise.then(null, function() {
|
|
self._findAllRecordArray = null;
|
|
return Ember.RSVP.reject.apply(null, arguments);
|
|
});
|
|
}
|
|
|
|
return isFetch ? promise : records;
|
|
},
|
|
|
|
findById: function(id) {
|
|
return this._findFetchById(id, false);
|
|
},
|
|
|
|
fetchById: function(id) {
|
|
return this._findFetchById(id, true);
|
|
},
|
|
|
|
_findFetchById: function(id, isFetch) {
|
|
var record = this.cachedRecordForId(id),
|
|
isLoaded = get(record, 'isLoaded'),
|
|
adapter = get(this, 'adapter'),
|
|
deferredOrPromise;
|
|
|
|
if (isLoaded) {
|
|
if (isFetch) {
|
|
return new Ember.RSVP.Promise(function(resolve, reject) {
|
|
resolve(record);
|
|
});
|
|
} else {
|
|
return record;
|
|
}
|
|
}
|
|
|
|
deferredOrPromise = this._fetchById(record, id);
|
|
|
|
return isFetch ? deferredOrPromise : record;
|
|
},
|
|
|
|
_currentBatchIds: null,
|
|
_currentBatchRecordArrays: null,
|
|
_currentBatchDeferreds: null,
|
|
|
|
reload: function(id) {
|
|
var record = this.cachedRecordForId(id);
|
|
record.set('isLoaded', false);
|
|
return this._fetchById(record, id);
|
|
},
|
|
|
|
_fetchById: function(record, id) {
|
|
var adapter = get(this, 'adapter'),
|
|
deferred;
|
|
|
|
if (adapter.findMany && !adapter.findMany.isUnimplemented) {
|
|
if (this._currentBatchIds) {
|
|
if (!contains(this._currentBatchIds, id)) { this._currentBatchIds.push(id); }
|
|
} else {
|
|
this._currentBatchIds = [id];
|
|
this._currentBatchRecordArrays = [];
|
|
}
|
|
|
|
deferred = Ember.Deferred.create();
|
|
|
|
//Attached the record to the deferred so we can resolove it later.
|
|
Ember.set(deferred, 'resolveWith', record);
|
|
|
|
if (!this._currentBatchDeferreds) { this._currentBatchDeferreds = []; }
|
|
this._currentBatchDeferreds.push(deferred);
|
|
|
|
Ember.run.scheduleOnce('data', this, this._executeBatch);
|
|
|
|
return deferred;
|
|
} else {
|
|
return adapter.find(record, id);
|
|
}
|
|
},
|
|
|
|
_executeBatch: function() {
|
|
var batchIds = this._currentBatchIds,
|
|
batchRecordArrays = this._currentBatchRecordArrays || [],
|
|
batchDeferreds = this._currentBatchDeferreds,
|
|
self = this,
|
|
requestIds = [],
|
|
promise,
|
|
i;
|
|
|
|
this._currentBatchIds = null;
|
|
this._currentBatchRecordArrays = null;
|
|
this._currentBatchDeferreds = null;
|
|
|
|
for (i = 0; i < batchIds.length; i++) {
|
|
if (!this.cachedRecordForId(batchIds[i]).get('isLoaded')) {
|
|
requestIds.push(batchIds[i]);
|
|
}
|
|
}
|
|
|
|
if (batchIds.length === 1) {
|
|
promise = get(this, 'adapter').find(this.cachedRecordForId(batchIds[0]), batchIds[0]);
|
|
} else {
|
|
var recordArray = Ember.RecordArray.create({_ids: batchIds});
|
|
if (requestIds.length === 0) {
|
|
promise = new Ember.RSVP.Promise(function(resolve, reject) { resolve(recordArray); });
|
|
recordArray.notifyLoaded();
|
|
} else {
|
|
promise = get(this, 'adapter').findMany(this, recordArray, requestIds);
|
|
}
|
|
}
|
|
|
|
promise.then(function() {
|
|
for (var i = 0, l = batchRecordArrays.length; i < l; i++) {
|
|
batchRecordArrays[i].loadForFindMany(self);
|
|
}
|
|
|
|
if (batchDeferreds) {
|
|
for (i = 0, l = batchDeferreds.length; i < l; i++) {
|
|
var resolveWith = Ember.get(batchDeferreds[i], 'resolveWith');
|
|
batchDeferreds[i].resolve(resolveWith);
|
|
}
|
|
}
|
|
}).then(null, function(errorXHR) {
|
|
if (batchDeferreds) {
|
|
for (var i = 0, l = batchDeferreds.length; i < l; i++) {
|
|
batchDeferreds[i].reject(errorXHR);
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
getCachedReferenceRecord: function(id){
|
|
var ref = this._getReferenceById(id);
|
|
if(ref) return ref.record;
|
|
return undefined;
|
|
},
|
|
|
|
cachedRecordForId: function(id) {
|
|
var record = this.getCachedReferenceRecord(id);
|
|
|
|
if (!record) {
|
|
var primaryKey = get(this, 'primaryKey'),
|
|
attrs = {isLoaded: false};
|
|
attrs[primaryKey] = id;
|
|
record = this.create(attrs);
|
|
var sideloadedData = this.sideloadedData && this.sideloadedData[id];
|
|
if (sideloadedData) {
|
|
record.load(id, sideloadedData);
|
|
}
|
|
}
|
|
|
|
return record;
|
|
},
|
|
|
|
|
|
addToRecordArrays: function(record) {
|
|
if (this._findAllRecordArray) {
|
|
this._findAllRecordArray.pushObject(record);
|
|
}
|
|
if (this.recordArrays) {
|
|
this.recordArrays.forEach(function(recordArray) {
|
|
if (recordArray instanceof Ember.FilteredRecordArray) {
|
|
recordArray.registerObserversOnRecord(record);
|
|
recordArray.updateFilterForRecord(record);
|
|
} else {
|
|
recordArray.pushObject(record);
|
|
}
|
|
});
|
|
}
|
|
},
|
|
|
|
unload: function (record) {
|
|
this.removeFromRecordArrays(record);
|
|
var primaryKey = record.get(get(this, 'primaryKey'));
|
|
this.removeFromCache(primaryKey);
|
|
},
|
|
|
|
clearCache: function () {
|
|
this.sideloadedData = undefined;
|
|
this._referenceCache = undefined;
|
|
},
|
|
|
|
removeFromCache: function (key) {
|
|
if (this.sideloadedData && this.sideloadedData[key]) {
|
|
delete this.sideloadedData[key];
|
|
}
|
|
if(this._referenceCache && this._referenceCache[key]) {
|
|
delete this._referenceCache[key];
|
|
}
|
|
},
|
|
|
|
removeFromRecordArrays: function(record) {
|
|
if (this._findAllRecordArray) {
|
|
this._findAllRecordArray.removeObject(record);
|
|
}
|
|
if (this.recordArrays) {
|
|
this.recordArrays.forEach(function(recordArray) {
|
|
recordArray.removeObject(record);
|
|
});
|
|
}
|
|
},
|
|
|
|
// FIXME
|
|
findFromCacheOrLoad: function(data) {
|
|
var record;
|
|
if (!data[get(this, 'primaryKey')]) {
|
|
record = this.create({isLoaded: false});
|
|
} else {
|
|
record = this.cachedRecordForId(data[get(this, 'primaryKey')]);
|
|
}
|
|
// set(record, 'data', data);
|
|
record.load(data[get(this, 'primaryKey')], data);
|
|
return record;
|
|
},
|
|
|
|
registerRecordArray: function(recordArray) {
|
|
if (!this.recordArrays) { this.recordArrays = []; }
|
|
this.recordArrays.push(recordArray);
|
|
},
|
|
|
|
unregisterRecordArray: function(recordArray) {
|
|
if (!this.recordArrays) { return; }
|
|
Ember.A(this.recordArrays).removeObject(recordArray);
|
|
},
|
|
|
|
forEachCachedRecord: function(callback) {
|
|
if (!this._referenceCache) { this._referenceCache = {}; }
|
|
var ids = Object.keys(this._referenceCache);
|
|
ids.map(function(id) {
|
|
return this._getReferenceById(id).record;
|
|
}, this).forEach(callback);
|
|
},
|
|
|
|
load: function(hashes) {
|
|
if (Ember.typeOf(hashes) !== 'array') { hashes = [hashes]; }
|
|
|
|
if (!this.sideloadedData) { this.sideloadedData = {}; }
|
|
|
|
for (var i = 0, l = hashes.length; i < l; i++) {
|
|
var hash = hashes[i],
|
|
primaryKey = hash[get(this, 'primaryKey')],
|
|
record = this.getCachedReferenceRecord(primaryKey);
|
|
|
|
if (record) {
|
|
record.load(primaryKey, hash);
|
|
} else {
|
|
this.sideloadedData[primaryKey] = hash;
|
|
}
|
|
}
|
|
},
|
|
|
|
_getReferenceById: function(id) {
|
|
if (!this._referenceCache) { this._referenceCache = {}; }
|
|
return this._referenceCache[id];
|
|
},
|
|
|
|
_getOrCreateReferenceForId: function(id) {
|
|
var reference = this._getReferenceById(id);
|
|
|
|
if (!reference) {
|
|
reference = this._createReference(id);
|
|
}
|
|
|
|
return reference;
|
|
},
|
|
|
|
_createReference: function(id) {
|
|
if (!this._referenceCache) { this._referenceCache = {}; }
|
|
|
|
Ember.assert('The id ' + id + ' has alread been used with another record of type ' + this.toString() + '.', !id || !this._referenceCache[id]);
|
|
|
|
var reference = {
|
|
id: id,
|
|
clientId: this._clientIdCounter++
|
|
};
|
|
|
|
this._cacheReference(reference);
|
|
|
|
return reference;
|
|
},
|
|
|
|
_cacheReference: function(reference) {
|
|
// if we're creating an item, this process will be done
|
|
// later, once the object has been persisted.
|
|
if (reference.id) {
|
|
this._referenceCache[reference.id] = reference;
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
})();
|
|
|
|
(function() {
|
|
|
|
var get = Ember.get;
|
|
|
|
Ember.hasMany = function(type, options) {
|
|
options = options || {};
|
|
|
|
var meta = { type: type, isRelationship: true, options: options, kind: 'hasMany' },
|
|
key = options.key;
|
|
|
|
return Ember.computed(function() {
|
|
if (typeof type === "string") {
|
|
type = Ember.get(Ember.lookup, type);
|
|
}
|
|
|
|
return this.getHasMany(key, type, meta);
|
|
}).property().meta(meta);
|
|
};
|
|
|
|
Ember.Model.reopen({
|
|
getHasMany: function(key, type, meta) {
|
|
var embedded = meta.options.embedded,
|
|
collectionClass = embedded ? Ember.EmbeddedHasManyArray : Ember.HasManyArray;
|
|
|
|
var collection = collectionClass.create({
|
|
parent: this,
|
|
modelClass: type,
|
|
content: this._getHasManyContent(key, type, embedded),
|
|
embedded: embedded,
|
|
key: key,
|
|
relationshipKey: meta.relationshipKey
|
|
});
|
|
|
|
this._registerHasManyArray(collection);
|
|
|
|
return collection;
|
|
}
|
|
});
|
|
|
|
|
|
})();
|
|
|
|
(function() {
|
|
|
|
var get = Ember.get,
|
|
set = Ember.set;
|
|
|
|
function getType() {
|
|
if (typeof this.type === "string") {
|
|
this.type = Ember.get(Ember.lookup, this.type);
|
|
}
|
|
return this.type;
|
|
}
|
|
|
|
Ember.belongsTo = function(type, options) {
|
|
options = options || {};
|
|
|
|
var meta = { type: type, isRelationship: true, options: options, kind: 'belongsTo', getType: getType },
|
|
relationshipKey = options.key;
|
|
|
|
return Ember.computed(function(key, value, oldValue) {
|
|
type = meta.getType();
|
|
|
|
var dirtyAttributes = get(this, '_dirtyAttributes'),
|
|
createdDirtyAttributes = false;
|
|
|
|
if (!dirtyAttributes) {
|
|
dirtyAttributes = [];
|
|
createdDirtyAttributes = true;
|
|
}
|
|
|
|
if (arguments.length > 1) {
|
|
if (value) {
|
|
Ember.assert(Ember.String.fmt('Attempted to set property of type: %@ with a value of type: %@',
|
|
[value.constructor, type]),
|
|
value instanceof type);
|
|
|
|
if (oldValue !== value) {
|
|
dirtyAttributes.pushObject(key);
|
|
} else {
|
|
dirtyAttributes.removeObject(key);
|
|
}
|
|
|
|
if (createdDirtyAttributes) {
|
|
set(this, '_dirtyAttributes', dirtyAttributes);
|
|
}
|
|
}
|
|
return value === undefined ? null : value;
|
|
} else {
|
|
return this.getBelongsTo(relationshipKey, type, meta);
|
|
}
|
|
}).property('_data').meta(meta);
|
|
};
|
|
|
|
Ember.Model.reopen({
|
|
getBelongsTo: function(key, type, meta) {
|
|
var idOrAttrs = get(this, '_data.' + key),
|
|
record;
|
|
|
|
if (Ember.isNone(idOrAttrs)) {
|
|
return null;
|
|
}
|
|
|
|
if (meta.options.embedded) {
|
|
var primaryKey = get(type, 'primaryKey'),
|
|
id = idOrAttrs[primaryKey];
|
|
record = type.create({ isLoaded: false, id: id });
|
|
record.load(id, idOrAttrs);
|
|
} else {
|
|
record = type.find(idOrAttrs);
|
|
}
|
|
|
|
return record;
|
|
}
|
|
});
|
|
|
|
|
|
})();
|
|
|
|
(function() {
|
|
|
|
var get = Ember.get,
|
|
set = Ember.set,
|
|
meta = Ember.meta;
|
|
|
|
Ember.Model.dataTypes = {};
|
|
|
|
Ember.Model.dataTypes[Date] = {
|
|
deserialize: function(string) {
|
|
if (!string) { return null; }
|
|
return new Date(string);
|
|
},
|
|
serialize: function (date) {
|
|
if (!date) { return null; }
|
|
return date.toISOString();
|
|
},
|
|
isEqual: function(obj1, obj2) {
|
|
if (obj1 instanceof Date) { obj1 = this.serialize(obj1); }
|
|
if (obj2 instanceof Date) { obj2 = this.serialize(obj2); }
|
|
return obj1 === obj2;
|
|
}
|
|
};
|
|
|
|
Ember.Model.dataTypes[Number] = {
|
|
deserialize: function(string) {
|
|
if (!string && string !== 0) { return null; }
|
|
return Number(string);
|
|
},
|
|
serialize: function (number) {
|
|
if (!number && number !== 0) { return null; }
|
|
return Number(number);
|
|
}
|
|
};
|
|
|
|
function deserialize(value, type) {
|
|
if (type && type.deserialize) {
|
|
return type.deserialize(value);
|
|
} else if (type && Ember.Model.dataTypes[type]) {
|
|
return Ember.Model.dataTypes[type].deserialize(value);
|
|
} else {
|
|
return value;
|
|
}
|
|
}
|
|
|
|
function serialize(value, type) {
|
|
if (type && type.serialize) {
|
|
return type.serialize(value);
|
|
} else if (type && Ember.Model.dataTypes[type]) {
|
|
return Ember.Model.dataTypes[type].serialize(value);
|
|
} else {
|
|
return value;
|
|
}
|
|
}
|
|
|
|
Ember.attr = function(type, options) {
|
|
return Ember.computed(function(key, value) {
|
|
var data = get(this, '_data'),
|
|
dataKey = this.dataKey(key),
|
|
dataValue = data && get(data, dataKey),
|
|
beingCreated = meta(this).proto === this,
|
|
dirtyAttributes = get(this, '_dirtyAttributes'),
|
|
createdDirtyAttributes = false;
|
|
|
|
if (!dirtyAttributes) {
|
|
dirtyAttributes = [];
|
|
createdDirtyAttributes = true;
|
|
}
|
|
|
|
if (arguments.length === 2) {
|
|
if (beingCreated) {
|
|
if (!data) {
|
|
data = {};
|
|
set(this, '_data', data);
|
|
}
|
|
dataValue = data[dataKey] = value;
|
|
}
|
|
|
|
if (dataValue !== serialize(value, type)) {
|
|
dirtyAttributes.pushObject(key);
|
|
} else {
|
|
dirtyAttributes.removeObject(key);
|
|
}
|
|
|
|
if (createdDirtyAttributes) {
|
|
set(this, '_dirtyAttributes', dirtyAttributes);
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
return this.getAttr(key, deserialize(dataValue, type));
|
|
}).property('_data').meta({isAttribute: true, type: type, options: options});
|
|
};
|
|
|
|
|
|
})();
|
|
|
|
(function() {
|
|
|
|
var get = Ember.get;
|
|
|
|
Ember.RESTAdapter = Ember.Adapter.extend({
|
|
find: function(record, id) {
|
|
var url = this.buildURL(record.constructor, id),
|
|
self = this;
|
|
|
|
return this.ajax(url).then(function(data) {
|
|
self.didFind(record, id, data);
|
|
return record;
|
|
});
|
|
},
|
|
|
|
didFind: function(record, id, data) {
|
|
var rootKey = get(record.constructor, 'rootKey'),
|
|
dataToLoad = rootKey ? data[rootKey] : data;
|
|
|
|
record.load(id, dataToLoad);
|
|
},
|
|
|
|
findAll: function(klass, records) {
|
|
var url = this.buildURL(klass),
|
|
self = this;
|
|
|
|
return this.ajax(url).then(function(data) {
|
|
self.didFindAll(klass, records, data);
|
|
return records;
|
|
});
|
|
},
|
|
|
|
didFindAll: function(klass, records, data) {
|
|
var collectionKey = get(klass, 'collectionKey'),
|
|
dataToLoad = collectionKey ? data[collectionKey] : data;
|
|
|
|
records.load(klass, dataToLoad);
|
|
},
|
|
|
|
findQuery: function(klass, records, params) {
|
|
var url = this.buildURL(klass),
|
|
self = this;
|
|
|
|
return this.ajax(url, params).then(function(data) {
|
|
self.didFindQuery(klass, records, params, data);
|
|
return records;
|
|
});
|
|
},
|
|
|
|
didFindQuery: function(klass, records, params, data) {
|
|
var collectionKey = get(klass, 'collectionKey'),
|
|
dataToLoad = collectionKey ? data[collectionKey] : data;
|
|
|
|
records.load(klass, dataToLoad);
|
|
},
|
|
|
|
createRecord: function(record) {
|
|
var url = this.buildURL(record.constructor),
|
|
self = this;
|
|
|
|
return this.ajax(url, record.toJSON(), "POST").then(function(data) {
|
|
self.didCreateRecord(record, data);
|
|
return record;
|
|
});
|
|
},
|
|
|
|
didCreateRecord: function(record, data) {
|
|
var rootKey = get(record.constructor, 'rootKey'),
|
|
primaryKey = get(record.constructor, 'primaryKey'),
|
|
dataToLoad = rootKey ? data[rootKey] : data;
|
|
record.load(dataToLoad[primaryKey], dataToLoad);
|
|
record.didCreateRecord();
|
|
},
|
|
|
|
saveRecord: function(record) {
|
|
var primaryKey = get(record.constructor, 'primaryKey'),
|
|
url = this.buildURL(record.constructor, get(record, primaryKey)),
|
|
self = this;
|
|
|
|
return this.ajax(url, record.toJSON(), "PUT").then(function(data) { // TODO: Some APIs may or may not return data
|
|
self.didSaveRecord(record, data);
|
|
return record;
|
|
});
|
|
},
|
|
|
|
didSaveRecord: function(record, data) {
|
|
record.didSaveRecord();
|
|
},
|
|
|
|
deleteRecord: function(record) {
|
|
var primaryKey = get(record.constructor, 'primaryKey'),
|
|
url = this.buildURL(record.constructor, get(record, primaryKey)),
|
|
self = this;
|
|
|
|
return this.ajax(url, record.toJSON(), "DELETE").then(function(data) { // TODO: Some APIs may or may not return data
|
|
self.didDeleteRecord(record, data);
|
|
});
|
|
},
|
|
|
|
didDeleteRecord: function(record, data) {
|
|
record.didDeleteRecord();
|
|
},
|
|
|
|
ajax: function(url, params, method, settings) {
|
|
return this._ajax(url, params, (method || "GET"), settings);
|
|
},
|
|
|
|
buildURL: function(klass, id) {
|
|
var urlRoot = get(klass, 'url');
|
|
if (!urlRoot) { throw new Error('Ember.RESTAdapter requires a `url` property to be specified'); }
|
|
|
|
if (!Ember.isEmpty(id)) {
|
|
return urlRoot + "/" + id + ".json";
|
|
} else {
|
|
return urlRoot + ".json";
|
|
}
|
|
},
|
|
|
|
ajaxSettings: function(url, method) {
|
|
return {
|
|
url: url,
|
|
type: method,
|
|
dataType: "json"
|
|
};
|
|
},
|
|
|
|
_ajax: function(url, params, method, settings) {
|
|
if (!settings) {
|
|
settings = this.ajaxSettings(url, method);
|
|
}
|
|
|
|
return new Ember.RSVP.Promise(function(resolve, reject) {
|
|
if (params) {
|
|
if (method === "GET") {
|
|
settings.data = params;
|
|
} else {
|
|
settings.contentType = "application/json; charset=utf-8";
|
|
settings.data = JSON.stringify(params);
|
|
}
|
|
}
|
|
|
|
settings.success = function(json) {
|
|
Ember.run(null, resolve, json);
|
|
};
|
|
|
|
settings.error = function(jqXHR, textStatus, errorThrown) {
|
|
// https://github.com/ebryn/ember-model/issues/202
|
|
if (jqXHR) {
|
|
jqXHR.then = null;
|
|
}
|
|
|
|
Ember.run(null, reject, jqXHR);
|
|
};
|
|
|
|
|
|
Ember.$.ajax(settings);
|
|
});
|
|
}
|
|
});
|
|
|
|
|
|
})();
|
|
|
|
(function() {
|
|
|
|
var get = Ember.get;
|
|
|
|
Ember.LoadPromise = Ember.Object.extend(Ember.DeferredMixin, {
|
|
init: function() {
|
|
this._super.apply(this, arguments);
|
|
|
|
var target = get(this, 'target');
|
|
|
|
if (get(target, 'isLoaded') && !get(target, 'isNew')) {
|
|
this.resolve(target);
|
|
} else {
|
|
target.one('didLoad', this, function() {
|
|
this.resolve(target);
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
Ember.loadPromise = function(target) {
|
|
if (Ember.isNone(target)) {
|
|
return null;
|
|
} else if (target.then) {
|
|
return target;
|
|
} else {
|
|
return Ember.LoadPromise.create({target: target});
|
|
}
|
|
};
|
|
|
|
|
|
})();
|
|
|
|
(function() {
|
|
|
|
// This is a debug adapter for the Ember Extension, don't let the fact this is called an "adapter" confuse you.
|
|
// Most copied from: https://github.com/emberjs/data/blob/master/packages/ember-data/lib/system/debug/debug_adapter.js
|
|
|
|
if (!Ember.DataAdapter) { return; }
|
|
|
|
var get = Ember.get, capitalize = Ember.String.capitalize, underscore = Ember.String.underscore;
|
|
|
|
var DebugAdapter = Ember.DataAdapter.extend({
|
|
getFilters: function() {
|
|
return [
|
|
{ name: 'isNew', desc: 'New' },
|
|
{ name: 'isModified', desc: 'Modified' },
|
|
{ name: 'isClean', desc: 'Clean' }
|
|
];
|
|
},
|
|
|
|
detect: function(klass) {
|
|
return klass !== Ember.Model && Ember.Model.detect(klass);
|
|
},
|
|
|
|
columnsForType: function(type) {
|
|
var columns = [], count = 0, self = this;
|
|
Ember.A(get(type.proto(), 'attributes')).forEach(function(name, meta) {
|
|
if (count++ > self.attributeLimit) { return false; }
|
|
var desc = capitalize(underscore(name).replace('_', ' '));
|
|
columns.push({ name: name, desc: desc });
|
|
});
|
|
return columns;
|
|
},
|
|
|
|
getRecords: function(type) {
|
|
var records = [];
|
|
type.forEachCachedRecord(function(record) { records.push(record); });
|
|
return records;
|
|
},
|
|
|
|
getRecordColumnValues: function(record) {
|
|
var self = this, count = 0,
|
|
columnValues = { id: get(record, 'id') };
|
|
|
|
record.get('attributes').forEach(function(key) {
|
|
if (count++ > self.attributeLimit) {
|
|
return false;
|
|
}
|
|
var value = get(record, key);
|
|
columnValues[key] = value;
|
|
});
|
|
return columnValues;
|
|
},
|
|
|
|
getRecordKeywords: function(record) {
|
|
var keywords = [], keys = Ember.A(['id']);
|
|
record.get('attributes').forEach(function(key) {
|
|
keys.push(key);
|
|
});
|
|
keys.forEach(function(key) {
|
|
keywords.push(get(record, key));
|
|
});
|
|
return keywords;
|
|
},
|
|
|
|
getRecordFilterValues: function(record) {
|
|
return {
|
|
isNew: record.get('isNew'),
|
|
isModified: record.get('isDirty') && !record.get('isNew'),
|
|
isClean: !record.get('isDirty')
|
|
};
|
|
},
|
|
|
|
getRecordColor: function(record) {
|
|
var color = 'black';
|
|
if (record.get('isNew')) {
|
|
color = 'green';
|
|
} else if (record.get('isDirty')) {
|
|
color = 'blue';
|
|
}
|
|
return color;
|
|
},
|
|
|
|
observeRecord: function(record, recordUpdated) {
|
|
var releaseMethods = Ember.A(), self = this,
|
|
keysToObserve = Ember.A(['id', 'isNew', 'isDirty']);
|
|
|
|
record.get('attributes').forEach(function(key) {
|
|
keysToObserve.push(key);
|
|
});
|
|
|
|
keysToObserve.forEach(function(key) {
|
|
var handler = function() {
|
|
recordUpdated(self.wrapRecord(record));
|
|
};
|
|
Ember.addObserver(record, key, handler);
|
|
releaseMethods.push(function() {
|
|
Ember.removeObserver(record, key, handler);
|
|
});
|
|
});
|
|
|
|
var release = function() {
|
|
releaseMethods.forEach(function(fn) { fn(); } );
|
|
};
|
|
|
|
return release;
|
|
}
|
|
});
|
|
|
|
Ember.onLoad('Ember.Application', function(Application) {
|
|
Application.initializer({
|
|
name: "dataAdapter",
|
|
|
|
initialize: function(container, application) {
|
|
application.register('dataAdapter:main', DebugAdapter);
|
|
}
|
|
});
|
|
});
|
|
|
|
})();
|