I am trying to auto save changes made to a text area.
My first approach was to have a function that fires on change, debounce the calls using ember-concurrently
, set the updated model within component and have the save action bubble up to parent.
export default Ember.Component.extend({
saveBody: task(function * (body) {
yield timeout(1000); // debounce calls
let note = this.get('note');
note.set('body', body);
this.sendAction('save', note); // tell parent to save model
}).restartable(), // run only for the most recent change
actions: {
bodyWasUpdated(changed) { // trigged on change
this.get('saveBody').perform(changed);
}
}
});
My problem is that when the input is saved, the model is also updated, so the cursor moves to the start of position rather than staying in place as user continues to type.
My temporary workaround is to use willTransition
to save the changes only if user transitions away from the route:
export default Ember.Route.extend({
...
actions: {
willTransition(transition) {
let note = this.controller.get('model.note');
if (note && note.get('hasDirtyAttributes')) {
this.controller.get('saveLatest').perform();
}
}
}
});
This solution works well if the user stays inside the app, but not if he or she refreshes the page or goes to an external url.
I can’t seem to figure out a way to save changes to a model, without updating the model until the user is done (to prevent cursor movement).
Is there a better way to autosave (or withhold) changes made to models?