errcw
errcw

Reputation: 329

Backbone.js view of model containing collection?

In my Backbone.js app I have a Model that contains a Collection. To support fetching that model from the back end I override the parse method to transform the array in the JSON response to a collection instance. It looks something like this:

class SomeModel extends Backbone.Model
  defaults: ->
    collection: new SomeCollection([new SomeModel(attr: value)])

  parse: (res) ->
    res.collection = new SomeCollection(res.collection)
    res

class SomeCollection extends Backbone.Collection
  model: SomeOtherModel

class SomeCollectionView extends Backbone.View
  el: $('collection-view')

My problems is that while SomeCollectionView is bound to an existing instance of SomeCollection, when calling SomeModel.fetch() that instance is replaced and the view is no longer valid. I could call remove() on the old view and instantiate a new one but my SomeCollectionView is layered on top of existing HTML (not built from a template) and calling remove pulls out the element from the DOM. Moreover, I would much prefer if my view could simply react to a change event rather than requiring reconstruction.

Upvotes: 1

Views: 1679

Answers (1)

PL J
PL J

Reputation: 312

I did stuff like you said (collection in model) from different "side" which would work here. When I had a model that had a Collection I used events in the model to create collection.

class ModelA extends Backbone.Model
  initialize: ->
    bind("change", @initializeCollection)

  initializeCollection: ->
    if !@collection
      @collection = new Collection(@attributes.collection) 
    else
      @collection.set(@attributes.collection)

The rest is the same so I won't put it in.

Also if you go deeper: modelA -> collecionB -> modelB -> collectionC -> modelC Than in modelB in constructor you can create collectionC (providing you don't reuse it)

[Edit] I've got another idea:

class ModelA extends Backbone.Model
  parse: (resp) ->
    if @attributes.collection
      @attributes.collection.set(resp.collection)
      delete resp.collection
    else
      resp.collection = new Collection(resp.collection)
    resp

Upvotes: 2

Related Questions