表示树数据的骨干集合

时间:2011-05-17 05:49:59

标签: javascript backbone.js

我想以树的形式将json数据加载到Backbone Collection中。我不能这样做。谁能解释我做错了什么?

我非常简单的模型:

CTreeDataItem = Backbone.Model.extend(
{
});
CTreeDataItems = Backbone.Collection.extend(
{
    model: CTreeDataItem
});

我的负担是:

    var treeJs =
        [
            { id: "tvRoot", title: 'Root', cssClass: 'root',
                items: [
                    { id: "ti1", title: 'Item1', cssClass: 'item',
                        items: [
                            { id: "ti11", title: 'SubItem11', cssClass: 'subitem'},
                            { id: "ti12", title: 'SubItem12', cssClass: 'subitem'}]},
                    { id: "ti2", title: 'Item2', cssClass: 'item',},
                    { id: "ti3", title: 'Item3', cssClass: 'item', 
                        items: [
                            { id: "ti31", title: 'SubItem31', cssClass: 'subitem'},
                            { id: "ti32", title: 'SubItem32', cssClass: 'subitem'},
                            { id: "ti33", title: 'SubItem33', cssClass: 'subitem'}]}]
        }];
    this.TreeData = new CTreeDataItems();
    this.TreeData.add(treeJs);

2 个答案:

答案 0 :(得分:24)

尝试使用Model作为节点表示树,并且每个节点包含Collection个子节点:

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"

编辑2011-05-18:如果要展平树并维护对每个节点在树中具有的父级的引用:

// 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"

希望这就是你所追求的目标。

答案 1 :(得分:4)

您需要使用Backbone.Model parse方法,该方法在将数据传递给模型之前用于解析数据。您可以使用它将树的每个级别上的数据转换为表示这些集合上的项目的集合和模型。

然后在保存时,您必须覆盖模型上的toJSON方法,以便以与接收数据相同的方式返回数据的json表示。稍后Backbone.sync使用它将数据发送回服务器。默认情况下,它仅返回_.clone的{​​{1}},并且您也希望其中包含所有集合和集合模型。

所有人都欢呼骨干! :)