Reputation: 4185
I'm using Ember and Ember-Data and I'm trying to edit a record. The problem is that since inputs are two-way-bound to the model, modifying something in the form immediately changes the model throughout the application (even though I don't commit the changes). Hence, the changes reflect everywhere in the site even though they aren't stored.
What is the Ember way of editing records without modifying them until the user actually confirms the changes? Is there a way to clone models?
Upvotes: 1
Views: 247
Reputation: 3268
That's really funny, I just myself ran into this, came up with a solution, and documented it in my own Stack Overflow question at Calling myModel.save() Returning Outdated Model. Scroll down to the SOLUTION part, second bullet.
My perception is that this pattern, while very common, is still not well-documented in the Ember community. For example, see these recent discussions:
I solved this by doing the following:
willTransition
event in your route so that, whenever your page that is doing the editing is transitioned out of, you can execute code right before that happens. Note that this covers both clicking your way out, or back-button'ing out. If the user closes their browser, these changes are lost anyway, so nothing extra needed to handle that situation.this.controller.get('model')
and look at the value of isDirty
with this.controller.get('model').get('isDirty')
. See http://emberjs.com/guides/models/working-with-records/ for discussion on how to understand isDirty
.isDirty
is true, then call rollback()
on your model as documented at http://emberjs.com/api/data/classes/DS.Model.html#method_rollback. I have a model orgUser
which has a belongsTo
relationship to a model orgPerson
. This relationship is set to { async: true }
. Rolling back the orgPerson
relationship worked like this for me:
Ember.Route.extend({
actions: {
willTransition: function( transition ) {
this.controller.get('model.orgPerson').then( function( value ) {
if ( value.get('isDirty') ) {
value.rollback();
}
});
},
}
}
Note that you (a) may not need to wrap your isDirty
call in a promise like I did (e.g. if you don't declare { async: true }
, and (b) you may just access value.get('model')
if you don't have a relationship to deal with.
Note also that, in my experience, myModel.rollback()
does not rollback any of the relationships! That may only be because I'm using { async: true }
for every relationship, but this is definitely something to watch out for.
Special thanks to @kingpin2k for pointing me in the right direction on my original SO post.
Upvotes: 3