Is it possible to nest collections within models?
I know that you can create new collections in the initialize callback of a model, and create references that you can pass back and forth between the collection and parent model. But is it possible to set the collection as part of the model, such that the JSON it exports looks like this:
{ blah: 'blah', myCollection: [ { foo: 'asdf', bar: 'qwer' }, { foo: 'asdf123', bar: 'qwer123' } ] }
If not, how do you handle syncing a model with related collections to the backend? Do you have to tap into backbone's sync and rebuild the JSON or is there something more seamless?
Sorry if this question has been answered elsewhere. I've looked around and seen some workarounds, but nothing that really answers what I'm looking for.
There are two approaches. The first is to define a root Model that gets everything. You override it's parse()
method to create sub-collections and sub-models for nested attributes, and override the toJSON()
method to convert back to the JSON structure, suitable for saving to the server.
This is perfectly acceptable for small subcollections. It takes a bit of programming, but if you can read the Backbone source code, how to do it should be, well, not obvious, but at least understandable.
Or you can use Backbone Relational, which does all the work for you.
Renato was close but "has" and "set" will not be available yet. I believe Reckoner pointed out part of that. Also, you will need to delete the property from the response, else it will override the default value.
_.extend(Backbone.Model.prototype, { parse: function(resp, xhr) { var attr, model, models, collection, options; for (var prop in resp) { if (this.defaults && this.defaults[prop]) { attr = this.defaults[prop]; if (attr instanceof Backbone.Model) { model = attr.clone(); model.set(resp[prop]); resp[prop] = model; } else if (attr instanceof Backbone.Collection) { models = attr.map(function (model) { return model.clone(); }); options = _.clone(attr.options); collection = new attr.constructor(models, options); collection.add(resp[prop]); resp[prop] = collection; } } } return resp; } });
Hope that helps someone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With