-
-
Save wycats/1164468 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DS = SC.Namespace.create(); | |
DS.property = function(transforms) { | |
transforms = transforms || {}; | |
return SC.computed(function(key, value) { | |
var data = SC.get(this, 'data'), value, val, | |
name = transforms.keyName || key; | |
var from = transforms && transforms.from; | |
var to = transforms && transforms.to; | |
var defaultValue = transforms.defaultValue; | |
// if the data hasn't been populated yet, return immediately | |
if (!data && !defaultValue) { return; } | |
if (value !== undefined) { | |
val = to ? to(value) : value; | |
SC.set(data, name, val); | |
} else { | |
value = SC.get(data, name); | |
if (value == undefined && defaultValue){ | |
value = defaultValue; | |
} | |
if (from) { value = from(value); } | |
} | |
return value; | |
}).property('data') | |
}; | |
DS.property.string = DS.property; | |
DS.property.integer = function(opts, keyName) { | |
return DS.property({ | |
defaultValue: (typeof(opts) == 'undefined') ? null : opts.defaultValue, | |
keyName: keyName, | |
from: function(serialized) { | |
return Number(serialized); | |
}, | |
to: function(deserialized) { | |
return String(deserialized); | |
} | |
}); | |
}; | |
DS.property.date = function(opts, keyName) { | |
return DS.property({ | |
defaultValue: (typeof(opts) == 'undefined') ? null : opts.defaultValue, | |
keyName: keyName, | |
from: function(raw) { | |
return new Date(raw); | |
}, | |
to: function(date) { | |
return JSON.stringify(date); | |
} | |
}) | |
}; | |
DS.hasMany = function(other, klass) { | |
return function() { | |
var keys = SC.get(this.get('data'), other); | |
if (keys) { | |
var recordArray = SC.ArrayProxy.create(), content = []; | |
keys.forEach(function(key) { | |
content.push(klass.load(key)); | |
}) | |
recordArray.set('content', content); | |
return recordArray; | |
} else { | |
return; | |
} | |
}.property('data.' + other + '.@each').cacheable() | |
}; | |
DS.RecordArray = SC.Object.extend(SC.Array, { | |
keys: null, | |
objectAt: function(idx) { | |
var keys = this.get('keys'), | |
klass = this.get('klass'); | |
if (!keys) { return; } | |
var id = keys.objectAt(idx); | |
return klass.loadRecord(id); | |
} | |
}); | |
DS.Record = SC.Object.extend({ | |
unknownProperty: function(key, value) { | |
var data = this.get('data'); | |
if (value !== undefined) { | |
SC.set(data, key, value); | |
} else { | |
value = SC.get(data, key); | |
} | |
return value; | |
}, | |
save: function() { | |
DS.saveRecord(this); | |
} | |
}); | |
DS.RECORDS = {}; | |
DS.recordHashFor = function(klass, id) { | |
if (!DS.RECORDS[SC.guidFor(klass)]) { DS.RECORDS[SC.guidFor(klass)] = {} } | |
var recordsHash = DS.RECORDS[SC.guidFor(klass)]; | |
return recordsHash[id]; | |
}; | |
DS.setRecordHash = function(klass, id, hash) { | |
if (!DS.RECORDS[SC.guidFor(klass)]) { DS.RECORDS[SC.guidFor(klass)] = {} } | |
var recordsHash = DS.RECORDS[SC.guidFor(klass)]; | |
recordsHash[id] = hash; | |
}; | |
// default method to look up a record by class and id. | |
// a record class can define its own load method for special behavior | |
// | |
// you can override this method to change the global loading behavior | |
DS.loadRecord = function(klass, id, force) { | |
var url = klass['instanceUrl'].fmt(id), | |
resource = klass['resource'], | |
instance = klass.create(); | |
if (!force) { | |
var recordHash = DS.recordHashFor(klass, id); | |
if (recordHash) { return instance.set('data', recordHash); } | |
} | |
$.ajax({ | |
url: url, | |
dataType: 'json', | |
success: function(json) { | |
console.log("ajax call successful, json data:", json); | |
DS.setRecordHash(klass, id, json[resource]); | |
instance.set('data', json[resource]); | |
} | |
}); | |
return instance; | |
}; | |
// params can be a Hash or a URL-encoded String | |
DS.loadRecords = function(klass, params) { | |
var url = klass['collectionUrl'], | |
resource = klass['resource'], | |
recordArray = SC.ArrayProxy.create({ ready: false }); | |
$.ajax({ | |
url: url, | |
data: params, | |
dataType: 'json', | |
success: function(json) { | |
console.log("ajax call successful, json data:", json); | |
var rawArray = json[resource], array = []; | |
rawArray.forEach(function(item) { | |
DS.setRecordHash(klass, item.id, item); | |
array.push(klass.create({ data: item })); | |
}); | |
recordArray.set('content', array); | |
recordArray.set('ready', true); | |
} | |
}); | |
// Return the recordArray right away. It will asynchronously | |
// be populated with data when the data comes in via Ajax | |
return recordArray; | |
} | |
DS.saveRecord = function(record) { | |
var url = SC.get(this.constructor, 'instanceUrl'); | |
url = url.fmt(this.get('id')); | |
// TODO: Something on success vs. failure | |
$.ajax({ | |
type: 'PUT', | |
url: url, | |
data: SC.get(this, 'data'), | |
dataType: 'json', | |
}); | |
} | |
DS.Record.reopenClass({ | |
// force forces the record to be loaded even if it's already | |
// been fetched | |
load: function(id, force) { | |
return DS.loadRecord(this, id, force); | |
}, | |
// fetches all records. You can specify params as a Hash or | |
// URL-encoded string to narrow down the results. Returned | |
// records will override existing records | |
// | |
// TODO: Make sure instantiated objects get the updated | |
// data hashes. | |
loadAll: function(params) { | |
return DS.loadRecords(this, params); | |
} | |
}); | |
/** | |
USAGE | |
// TODO: Convention over configuration for instance URL, resource | |
// name and class URL | |
Person = DS.Record.extend({ | |
firstName: DS.property.string({defaultValue: "Matt"}), | |
lastName: DS.property.string(), | |
fullName: function() { | |
return this.get('firstName') + ' ' + this.get('lastName'); | |
}.property('firstName', 'lastName') | |
}); | |
Person.reopenClass({ | |
collectionUrl: "/people", | |
instanceUrl: "/people/%@", | |
resource: "people" | |
}); | |
var person = Person.load(1); | |
var people = Person.loadAll(); // can use this wherever an | |
// Array is expected, like in | |
// an ArrayController | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment