Michal
Michal

Reputation: 618

Backbone.js saving model with attribute that is array of other models

im writing first open source Backbone.js app. The repository is here https://github.com/defrag/Backbone-Invoices

Im having problem with saving array of LineItems for Invoice. Well, only saving after editing, because it saves the line items from currently edited invoice, to all invoices in localstorage. Dunno why this is happening, they have always same Cids. The default line item while creating invoice have always cid0. Any help?

class window.Invoice extends Backbone.Model

  initialize: ->

  defaults:
    date: new Date
    number: '000001'
    seller_info: null
    buyer_info: null  
    line_items: [new LineItem]

The last thing i do not understand is why backbone isnt saving the nested attributes. As you will see in repo i do:

handleSubmit: (e) ->        
data = { 
  date : @$("input[name='date']").val(), 
  number : @$("input[name='number']").val(), 
  buyer_info : @$("textarea[name='buyer_info']").val(), 
  seller_info : @$("textarea[name='seller_info']").val(),
  line_items: @model.line_items.toJSON()
}    

if @model.isNew()
  invoices.create(data)
else
  @model.save(data)

e.preventDefault()
e.stopPropagation()    
$(@el).fadeOut 'fast', ->
  window.location.hash = "#"

The things is after editing form and changing values of line items, they do not change in collection. Adding new to invoice line items collection works. Any help? :) I have some hard time with understanding how everyhing works :)

You can check it here: http://backbone-invoices.brillante.pl/

Upvotes: 1

Views: 3013

Answers (1)

Derick Bailey
Derick Bailey

Reputation: 72868

default values are literal values, evaluated at the time of definition. this means that you are assigning the same instance of LineItem to the array, for every instance of Invoice.

The fix for this is simple: use a function to return the array. this way you get a new array of line items every time you create an invoice:

window.Invoice = Backbone.Model.extend({
  defaults: {
    date: function(){ return new Date(); },
    line_items: function(){ return [new LineItem()]; },
    other: "stuff"
  }
});

Upvotes: 8

Related Questions