Backbone - Collections nested in Models

12,916

Solution 1

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.

Solution 2

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.

Share:
12,916

Related videos on Youtube

Jon Raasch
Author by

Jon Raasch

Free-lance front end web developer, regular Smashing Magazine contributor, CSS, JavaScript, jQuery, HTML5, etc. Official Sealand royalty.

Updated on June 04, 2022

Comments

  • Jon Raasch
    Jon Raasch almost 2 years

    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.