diff --git a/Buildfile b/Buildfile index b5d75df..2ac85f6 100644 --- a/Buildfile +++ b/Buildfile @@ -4,4 +4,6 @@ # =========================================================================== # Add initial buildfile information here -config :all, :required => :sproutcore \ No newline at end of file +config :all, :required => :sproutcore + +proxy '/tasks', :to => 'todos.demo.sproutcore.com' diff --git a/apps/todos/core.js b/apps/todos/core.js index 285b6e5..d114b77 100644 --- a/apps/todos/core.js +++ b/apps/todos/core.js @@ -20,7 +20,7 @@ Todos = SC.Application.create( // of your model data. You can also set a data source on this store to // connect to a backend server. The default setup below connects the store // to any fixtures you define. - store: SC.Store.create().from(SC.Record.fixtures) + store: SC.Store.create({commitRecordsAutomatically: YES}).from('Todos.TaskDataSource') // TODO: Add global constants or singleton objects needed by your app here. diff --git a/apps/todos/data_sources/task.js b/apps/todos/data_sources/task.js new file mode 100644 index 0000000..4f87c67 --- /dev/null +++ b/apps/todos/data_sources/task.js @@ -0,0 +1,132 @@ +// ========================================================================== +// Project: Todos.TaskDataSource +// Copyright: ©2010 My Company, Inc. +// ========================================================================== +/*globals Todos */ + +sc_require('models/task'); +Todos.TASKS_QUERY = SC.Query.local(Todos.Task, { + orderBy: 'isDone,description' +}); + +/** @class + + (Document Your Data Source Here) + + @extends SC.DataSource +*/ +Todos.TaskDataSource = SC.DataSource.extend( +/** @scope Todos.TaskDataSource.prototype */ { + + // .......................................................... + // QUERY SUPPORT + // + + fetch: function(store, query) { + + if (query === Todos.TASKS_QUERY) { + SC.Request.getUrl('/tasks').header({'Accept': 'application/json'}).json() + .notify(this, 'didFetchTasks', store, query) + .send(); + return YES; + } + return NO; + }, + + didFetchTasks: function(response, store, query) { + if (SC.ok(response)) { + store.loadRecords(Todos.Task, response.get('body').content); + store.dataSourceDidFetchQuery(query); + + } else store.dataSourceDidErrorQuery(query, response); + }, + + // .......................................................... + // RECORD SUPPORT + // + + retrieveRecord: function(store, storeKey) { + if (SC.kindOf(store.recordTypeFor(storeKey), Todos.Task)) { + + var url = store.idFor(storeKey); + SC.Request.getUrl(url).header({ + 'Accept': 'application/json' + }).json() + .notify(this, 'didRetrieveTask', store, storeKey) + .send(); + return YES; + + } else return NO; + }, + + didRetrieveTask: function(response, store, storeKey) { + if (SC.ok(response)) { + var dataHash = response.get('body').content; + store.dataSourceDidComplete(storeKey, dataHash); + + } else store.dataSourceDidError(storeKey, response); + }, + + createRecord: function(store, storeKey) { + if (SC.kindOf(store.recordTypeFor(storeKey), Todos.Task)) { + + SC.Request.postUrl('/tasks').header({ + 'Accept': 'application/json' + }).json() + .notify(this, this.didCreateTask, store, storeKey) + .send(store.readDataHash(storeKey)); + return YES; + + } else return NO; + }, + + didCreateTask: function(response, store, storeKey) { + if (SC.ok(response)) { + // Adapted from parseUri 1.2.2 + // (c) Steven Levithan + // MIT License + var parser = /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/; + var url = parser.exec(response.header('Location'))[8]; + store.dataSourceDidComplete(storeKey, null, url); // update url + + } else store.dataSourceDidError(storeKey, response); + }, + + updateRecord: function(store, storeKey) { + if (SC.kindOf(store.recordTypeFor(storeKey), Todos.Task)) { + SC.Request.putUrl(store.idFor(storeKey)).header({ + 'Accept': 'application/json' + }).json() + .notify(this, this.didUpdateTask, store, storeKey) + .send(store.readDataHash(storeKey)); + return YES; + + } else return NO ; + }, + didUpdateTask: function(response, store, storeKey) { + if (SC.ok(response)) { + var data = response.get('body'); + if (data) data = data.content; // if hash is returned; use it. + store.dataSourceDidComplete(storeKey, data) ; + + } else store.dataSourceDidError(storeKey); + }, + + destroyRecord: function(store, storeKey) { + if (SC.kindOf(store.recordTypeFor(storeKey), Todos.Task)) { + SC.Request.deleteUrl(store.idFor(storeKey)).header({ + 'Accept': 'application/json' + }).json() + .notify(this, this.didDestroyTask, store, storeKey) + .send(); + return YES; + + } else return NO; + }, + didDestroyTask: function(response, store, storeKey) { + if (SC.ok(response)) { + store.dataSourceDidDestroy(storeKey); + } else store.dataSourceDidError(response); + } + +}) ; diff --git a/apps/todos/main.js b/apps/todos/main.js index 40643c3..73de6f6 100644 --- a/apps/todos/main.js +++ b/apps/todos/main.js @@ -24,8 +24,7 @@ Todos.main = function main() { // TODO: Set the content property on your primary controller // ex: Todos.contactsController.set('content',Todos.contacts); - var query = SC.Query.local(Todos.Task, { orderBy: 'isDone,description' }); - var tasks = Todos.store.find(query); + var tasks = Todos.store.find(Todos.TASKS_QUERY); Todos.tasksController.set('content', tasks); } ;