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