Chris Hanson
Chris Hanson

Reputation: 731

Backbone collection in collections

I'm building my first real web app using backbone and I'm struggling with nested resources.

This is a simplified version of the json response i'm working with:

{
  "id": 1,
  "title": "Test Survey",
  "groups": [
    {
      "id": 1,
      "title": "Basic Questions",
      "questions": [
        {
          "id": 1,
          "title": "Which is your favorite color?"
        },
        {
          "id": 2,
          "title": "Do you have any other hobbies?"
        }
      ]
    },
    {
      "id": 2,
      "title": "Working Questions",
      "questions": [
        {
          "id": 3,
          "title": "Do you think working exp is very important?"
        }
      ]
    }
  ]
}

Basically theres a Survey object which has many Groups, each Group has many Questions.

I can't seem to figure out a good way to get all this data into models/ collections.

What I currently have is:

// Models
var Question = Backbone.Model.extend({});
var Group    = Backbone.Model.extend({});
var Survey   = Backbone.Model.extend({ url: surveyURL });

// Collections
var GroupsCollection    = Backbone.Collection.extend({});
var QuestionsCollection = Backbone.Collection.extend({});

//Views
var SurveyView = Backbone.View.extend({
  ..
});

var GroupsCollectionView = Backbone.View.extend({
  ..
});

var QuestionsCollectionView = Backbone.View.extent({
  ..
});

var survey = new Survey({ groups: new GroupsCollection({model: Group}) });   
var groupsView  = new GroupsCollectionView({collection: survey.get('groups')});

This seems to work for nesting Groups in the Survey model, but how do I store the questions in a collection and then assign that to each model in the Groups collection?

As mentioned I'm relatively new to backbone, so if I'm going down the completely wrong path or there's a better way to do this please let me know.

Cheers.

Upvotes: 7

Views: 814

Answers (2)

louisdeb
louisdeb

Reputation: 439

The above answer was a bit heavy-weight for my case that lead me to this question. This may be helpful to anyone else searching.

I had created four collections. They were to be contained in a collection. A Collection View would contains four more Collections Views, whose child views (plain-old Views) would render the data.

When I created the wrapping collection

new Backbone.Collection([collectionA, collectionB, collectionC, collectionD])

I was returned a Collection that contained four models, all of which were Backbone models. Which was fine until those models didn't contain my collections.

This was solved by creating wrapping Models, that would each contain one of my four collections.

var wrapperModelA = new Backbone.Model({ collection: collectionA });
...
var wrapperModelD = new Backbone.Model({ collection: collectionD }); 

return new Backbone.Collection([wrapperModelA, ... , wrapperModelD]);

This preserved my collections and allowed me to create a nested collection structure without defining new classes.

Upvotes: 0

nikoshr
nikoshr

Reputation: 33344

I usually declare my sub collections as properties of my objects (I remove them from the attributes hash : in your example, that means referencing survey.groups instead of survey.get('groups')) and use model.parse to populate them.

With your Survey model :

var GroupsCollection = Backbone.Collection.extend({
    model: Group
});

var Survey = Backbone.Model.extend({
    initialize: function(data) {
        this.groups = new GroupsCollection();
        this.parse(data);
    },
    parse: function(data) {
        if (data.groups) {
            this.groups.reset(data.groups);
        }
        return _.omit(data, 'groups');
    }
});

Your Group class would be declared in a similar fashion. You would pass your data to the constructor:

var s = new Survey({
    "id": 1,
    "title": "Test Survey",
    "groups": [],
    ...
});

var g = s.groups.at(0); //first group
var q = g.questions.at(0); //first question in the first group

Your data is then traversed to build the whole hierarchy.

And a demo http://jsfiddle.net/nikoshr/947Vf/

Upvotes: 4

Related Questions