I just started working on backbone a week ago, please don’t mind if this question is silly. Alright, here’s what I am trying to do.
I have a model called Item and a collection called Items. There are two views, one to add the item and the other to list the items. The issue I am having is when I am trying to save the item, it gets saved correctly for the first time. The next time when I add a new item, the item is created successfully, but the previous item added also gets updated with the attributes of the new item. This happens to all the successive items being added.
I am guessing that all my models in the collection are being updated OR I need to have my own save method. I actually am not able to figure out what I am doing wrong. I just want to save the model in question with the view, not all the models in the collection. Would really appreciate some pointers.
Link to the demo.
Item add/edit view
define([
'jquery',
'use!underscore',
'use!backbone',
'mustache',
'models/item',
'views/bootstrap',
'text!templates/items/edit.mustache',
'text!templates/items/new.mustache',
'handlebars',
'bootstrap'
], function($, _, Backbone, Mustache, Item, Bootstrap, editTemplate, newTemplate, Handlebars){
var app = new Backbone.Router
var ItemEditView = Backbone.View.extend({
el: $('#page'),
events: {
'submit #new-item': 'saveItem',
'click .cancel': 'cancelItem'
},
initialize: function(options){
if (!this.model.isNew()) {
this.model.bind('change', this.render, this)
this.model.fetch()
}
},
render: function(){
var item = this.model.attributes
var template = this.model.isNew() ? newTemplate : editTemplate
var compiledTemplate = Mustache.render(template, item )
$(this.el).html(compiledTemplate)
if (this.model.isNew()) $('#itemName').focus()
return this
},
/*
* Event actions
*/
saveItem: function(e) {
e.preventDefault()
var item = {
name: $('#itemName').val(),
price: $('#itemPrice').val()
}
var self = this
this.model.save(item, {
success: function (model, response) {
app.navigate('items/'+model.id, {trigger: true, replace: true})
},
error: function (model, response) {
new Bootstrap.alert({ el: $('#page') }).render(response, 'error')
}
})
},
cancelItem: function (e) {
if (this.model.isNew())
app.navigate('items', {trigger: true, replace: true})
else
app.navigate('items/'+this.model.id, {trigger: true, replace: true})
}
})
return ItemEditView
})
Item model
define([
'use!underscore',
'use!backbone'
], function(_, Backbone) {
var Item = Backbone.Model.extend({
urlRoot: 'api/items',
idAttribute: '_id'
});
return Item;
});
Items collection
define([
'jquery',
'use!underscore',
'use!backbone',
'models/item'
], function($, _, Backbone, Item){
var Items = Backbone.Collection.extend({
model: Item,
url: 'api/items/'
});
return Items;
});
Link to the Source code (in case)
When you are done using your form, either the form is submitted or canceled you must either destroy or the view by calling ItemView.remove() or at least un-delegate events::
As the events are delegated to #page and your old views exist after creating new ones their save and cancel methods will still trigger until they are removed.