I want to load json data in form of a tree into Backbone Collection. I can\'t do this. Can anyone explain what I\'m doing wrong?
My very simple model:
CT
Try representing the tree with Model
as the node and each node containing a Collection
of its child nodes:
var CTreeDataItem = Backbone.Model.extend({
initialize: function() {
if (Array.isArray(this.get('items'))) {
this.set({items: new CTreeDataItemChildren(this.get('items'))});
}
}
});
// children collection
var CTreeDataItemChildren = Backbone.Collection.extend({
model: CTreeDataItem
});
// create
var treeData = new CTreeDataItemChildren(treeJs);
// access
treeData.at(0).get('items').at(1).get('title')
// returns "Item2"
EDIT 2011-05-18: If you want to flatten the tree and maintain a reference to the parent that each node had in the tree:
// flatten the tree outside of Backbone. Alternatively,
// you could override the constructor of the CTree collection
// to provide encapsulation
function flatten(parentID, arr) {
var out = [];
for (var i = 0; i < arr.length; i++) {
var node = arr[i];
node.parentID = parentID;
out.push(node);
if (Array.isArray(node.items))
Array.prototype.push.apply(out, flatten(node.id, node.items));
delete node.items;
}
return out;
}
// remove above code that would have provided nesting
var CTreeDataItem = Backbone.Model.extend({});
// children collection, as before
var CTreeDataItemCollection = Backbone.Collection.extend({
model: CTreeDataItem
});
// create
var treeData = new CTreeDataItemChildren(flatten('', treeJs));
// as before, but now there's the 'parentID' FK
treeData.at(3).get('parentID')
// returns "ti1"
Hope that's what you're after.
You need to use Backbone.Model parse method which is used to parse data before it gets passed to a model. You can use it to turn data on each level of your tree to Collections and Models representing items on these collections.
Then when saving you'd have to override the toJSON
method on the Model to return the json representation of your data the same way you receive it. It is later on used by Backbone.sync to send the data back to the server. By default it returns only _.clone
of your Model.attributes
and you want all the Collections and CollectionModels in there as well.
All hail the backbone! :)