Reputation: 1409
I'll try to describe this as succinctly as possible. Within the app I'm working on, Backbone models are saved and then they can be edited later. Currently, I have it setup where the functionality is entirely dynamic.
Example: this.model.set('attribute', value)
Standard stuff there. Here's the issue. The client wants the updated model not to be saved until the user explicitly clicks a save and finish button.
Previously, I was using this pattern for editing:
this.model = options.previousModel || new NamedBackboneModel({
id: this.model.get('id'),
attr: otherModel.get('attr')
});
I've made the properties and model names in that example generic but it worked great. Throughout the view I would use model.set('attr' value)
and it was perfect.
What's the best way I can make edits to the previousModel without immediately saving them to the previous model?
I looked at using a vanilla object to track changes, but I'm thinking there has to be a better way that is more inline with a typical Backbone pattern.
Naturally, I tried new NamedBackboneModel(options.previousModel.toJSON())
but because of a nested collection on the Model that didn't work as expected and would require some architectural changes.
I figured a clone on the previousModel would work but I didn't have any luck with that approach either. Thanks for any help and please let me know if I need to provide more clarification.
Upvotes: 0
Views: 1581
Reputation: 1409
I ended up using a combination of methods to make this work. I added store and revert functions to the model like so:
store: function() {
this._storedAttributes = _.clone(this.attributes);
this._storedCollection = _.clone(this.collection().toJSON());
},
revert: function() {
if (this._storedAttributes) {
this.set(this._storedAttributes, {
silent: true
});
this.collection.remove(this.collection.models, { silent: true });
this.collection.reset(this._storedCollection, { silent: true });
// For syncing local storage up the chain
if(!this.isNew()) { this.trigger('change'); }
}
},
Upvotes: 0
Reputation: 1870
I think you should pass {silent: true}
when you call model.set()
.
Then you can retrieve a list of previous values by calling model.previousAttributes()
to get all previous attributes. or model.previous("name")
to get specific attribute.
When you want to discard the previous attributes, you can call model.change()
to invoke 'change' event.
When you want to save, you can model.save({silent:false})
which will save and discard previous attributes, or passing {silent:true}
will keep previous changes.
Upvotes: 1