Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 248
Chris Hanson Avatar asked Sep 30 '13 12:09

Chris Hanson


1 Answers

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/

like image 195
nikoshr Avatar answered Oct 20 '22 18:10

nikoshr