Reputation: 329
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
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