Created
July 17, 2013 19:06
-
-
Save aboma/6023481 to your computer and use it in GitHub Desktop.
Universal edit controller mixin for ember.js. Use on all controllers that create, update and delete records.
This file contains 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
// Mixin to generalize model create/edit functionality | |
// for use in controllers. Typical use in route: | |
// Vilio.PortfolioEditRoute = Ember.Route.extend({ | |
// // create transaction and add model to it | |
// setupController: function(controller, model) { | |
// this._super(controller, model); | |
// this.store.transaction().add(model); | |
// }, | |
// events: { | |
// cancel: function() { | |
// this.controller.stopEditing(); | |
// ... | |
// }, | |
// save: function() { | |
// var route = this; | |
// this.controller.saveEdits().then(function() { | |
// console.log('saved'); | |
// route.transitionTo... | |
// }, function() { | |
// console.log('error saving'); | |
// }); | |
// }, | |
// remove : function(portfolio) { | |
// var route = this; | |
// this.controller.deleteRecord().then(function(){ | |
// console.log('deleted'); | |
// route.transitionTo... | |
// }, function() { | |
// console.log('error deleting'); | |
// }); | |
// } | |
// } | |
//}); | |
Vilio.EditModelControllerMixin = Ember.Mixin.create({ | |
needs:['message'], | |
// works for both save and edit by inspecting record states | |
// commit record if it has changed; returns promise of | |
// record create or update | |
saveEdits: function() { | |
var controller = this, | |
msgController = this.get('controllers.message'), | |
record = this.get('content'); | |
return new Em.RSVP.Promise(function(resolve, reject) { | |
// reset transaction if user wants to resubmit record | |
// that is invalid or in error state | |
if (!record.get('isValid') || record.get('isError')) { | |
this.resetRecordState(); | |
} | |
if (record.get('isDirty')) { | |
msgController.set('message', 'saving record'); | |
var method = record.get('isNew') === true ? 'didCreate' : 'didUpdate'; | |
// callback will show record once the id is available | |
record.one(method, controller, function() { | |
msgController.set('message', 'record saved'); | |
if (method === 'didUpdate') { | |
// resolve promise | |
resolve(record); | |
} else { | |
// observe for when id is created since we may need this | |
// for transition | |
record.addObserver('id', this, resolve); | |
} | |
}); | |
var errorHandler = function() { | |
var type = this.get('content.isError') ? 'error' : 'problem'; | |
msgController.set('message', type + ' saving record'); | |
this.get('content.transaction').rollback(); | |
// reject promise | |
reject(record); | |
}; | |
// callback for invalid or conflict response from server | |
record.one('becameInvalid', controller, errorHandler); | |
record.one('becameError', controller, errorHandler); | |
// trigger save | |
record.get('transaction').commit(); | |
} else { | |
msgController.set('message', 'no changes to save in model'); | |
resolve(record); | |
} | |
}); | |
}, | |
// returns promise to delete resource | |
deleteRecord: function() { | |
var controller = this, | |
msgController = this.get('controllers.message'), | |
record = this.get('content'); | |
return new Em.RSVP.Promise(function(resolve, reject) { | |
msgController.set('message', 'deleting record'); | |
record.one('didDelete', controller, function() { | |
msgController.set('message', 'record deleted'); | |
resolve(); | |
}); | |
record.one('didError', controller, function() { | |
msgController.set('message', 'error deleting record'); | |
reject(record); | |
}); | |
record.deleteRecord(); | |
controller.get('content.transaction').commit(); | |
}); | |
}, | |
stopEditing: function(callback) { | |
var controller = this; | |
return new Em.RSVP.Promise(function(resolve, reject) { | |
controller.get('content.transaction').rollback(); | |
resolve(); | |
}); | |
}, | |
// enable transaction to be submitted again | |
resetRecordState: function() { | |
var record = this.get('content'); | |
var state = record.get('id') ? 'loaded.updated.uncommitted' : 'loaded.created.uncommited'; | |
record.get('stateManager').transitionTo(state); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment