如何将嵌套数据显示到树中?

发布于 2024-12-07 11:22:29 字数 4516 浏览 1 评论 0 原文

进一步进步。请参阅 http://www.sencha.com/forum/showthread.php?153986-Empty-column-something-I-can-t-get-with-Ext.data.TreeStore-and-or- Ext.tree.Panel

我总是感谢任何进一步的建议。


我正在尝试开发一个简单的 extJS Ext 4.0.2a 脚本来将一些嵌套数据显示为拖放树。 为了尝试,我使用 http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.reader.Reader

数据以 users.json 文件形式给出:

{
"users": [
    {
        "id": 123,
        "name": "Ed",
        "orders": [
            {
                "id": 50,
                "total": 100,
                "order_items": [
                    {
                        "id"      : 20,
                        "price"   : 40,
                        "quantity": 2,
                        "product" : {
                            "id": 1000,
                            "name": "MacBook Pro"
                        }
                    },
                    {
                        "id"      : 21,
                        "price"   : 20,
                        "quantity": 3,
                        "product" : {
                            "id": 1001,
                            "name": "iPhone"
                        }
                    }
                ]
            }
        ]
    }
]
}

我希望显示数据作为一棵树,其第一级节点是用户,第二级节点是订单等。

从同一个文档中,我学习了如何定义我的模型(我相信):

    Ext.define("User", {
    extend: 'Ext.data.Model',
    fields: [
        'id', 'name'
    ],

    hasMany: {model: 'Order', name: 'orders'},

    proxy: {
        type: 'ajax', // rest
        url : 'users.json',
        reader: {
            type: 'json',
            root: 'users'
        }
    }
})

;

Ext.define("Order", {
    extend: 'Ext.data.Model',
    fields: [
        'id', 'total'
    ],

    hasMany  : {model: 'OrderItem', name: 'orderItems', associationKey: 'order_items'},
    belongsTo: 'User'
});

Ext.define("OrderItem", {
    extend: 'Ext.data.Model',
    fields: [
        'id', 'price', 'quantity', 'order_id', 'product_id'
    ],

    belongsTo: ['Order', {model: 'Product', associationKey: 'product'}]
});

Ext.define("Product", {
    extend: 'Ext.data.Model',
    fields: [
        'id', 'name'
    ],

    hasMany: 'OrderItem'
});

接下来,我定义一个树存储和一个树面板(对于某些选定的字段):

    var store = Ext.create('Ext.data.TreeStore', {
        model: 'User',
        autoLoad: true,
        autoSync: true,
     root: {
        name: "Root node",
        id: '0',
        expanded: true
    }, 
   sorters: [{
        property: 'id',
        direction: 'ASC' // DESC
    }]
});

var tree = Ext.create('Ext.tree.Panel', {
        store: store,  
    displayField: 'name', // what nodes display (default->text)
        columns: [{
        xtype: 'treecolumn',
        text: 'name',
        dataIndex: 'name',
        width: 150,
        sortable: true
    }, {
        text: 'total',
        dataIndex: 'total',
    width: 150,
        flex: 1,
        sortable: true
    }, {
        text: 'price',
        dataIndex: 'price',
    width: 50,
        flex: 1,
        sortable: true
    },{ 
        text: 'quantity',
        dataIndex: 'quantity',
    width: 150,
        flex: 1
    }, {
        text: 'id',
        dataIndex: 'id',
        flex: 1,
        width: 15,
        sortable: true
    }],
        collapsible: true,
        viewConfig: {
            plugins: {
                ptype: 'treeviewdragdrop',  // see Ext.tree.plugin.TreeViewDragDrop
                nodeHighlightColor : '7B68EE',
        nodeHighlightOnDrop : true, 
        nodeHighlightOnRepair: true, 
        enableDrag: true, 
        enableDrop: true
            }
       },
        renderTo: 'tree-div',
        height: 300,
        width: 900,
        title: 'Items',
        useArrows: true,
        dockedItems: [{
            xtype: 'toolbar',
            items: [{
                text: 'Expand All',
                handler: function(){
                    tree.expandAll();
                }
            }, {
                text: 'Collapse All',
                handler: function(){
                    tree.collapseAll();
                }
            }]
        }]
    });
});

我看到面板、根和第一级用户(作为子节点)的根)。我没有看到任何子节点(orders、order_items 等)。

我仔细查看了一些帖子,改进了很多东西,但仍然没有找到可行的解决方案。

Further progress. Please see at http://www.sencha.com/forum/showthread.php?153986-Empty-column-something-I-can-t-get-with-Ext.data.TreeStore-and-or-Ext.tree.Panel

I always appreciate any further advise.


I am trying to develop a simple extJS Ext 4.0.2a script to display some nested data as a Drag&Drop tree.
To try, I use a simple example from http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.reader.Reader

Data are given as a users.json file:

{
"users": [
    {
        "id": 123,
        "name": "Ed",
        "orders": [
            {
                "id": 50,
                "total": 100,
                "order_items": [
                    {
                        "id"      : 20,
                        "price"   : 40,
                        "quantity": 2,
                        "product" : {
                            "id": 1000,
                            "name": "MacBook Pro"
                        }
                    },
                    {
                        "id"      : 21,
                        "price"   : 20,
                        "quantity": 3,
                        "product" : {
                            "id": 1001,
                            "name": "iPhone"
                        }
                    }
                ]
            }
        ]
    }
]
}

I wish to display data as a tree, whose first level nodes are users, second level nodes are orders, and so on.

From the same doc, I learn how to define my models (I believe):

    Ext.define("User", {
    extend: 'Ext.data.Model',
    fields: [
        'id', 'name'
    ],

    hasMany: {model: 'Order', name: 'orders'},

    proxy: {
        type: 'ajax', // rest
        url : 'users.json',
        reader: {
            type: 'json',
            root: 'users'
        }
    }
})

;

Ext.define("Order", {
    extend: 'Ext.data.Model',
    fields: [
        'id', 'total'
    ],

    hasMany  : {model: 'OrderItem', name: 'orderItems', associationKey: 'order_items'},
    belongsTo: 'User'
});

Ext.define("OrderItem", {
    extend: 'Ext.data.Model',
    fields: [
        'id', 'price', 'quantity', 'order_id', 'product_id'
    ],

    belongsTo: ['Order', {model: 'Product', associationKey: 'product'}]
});

Ext.define("Product", {
    extend: 'Ext.data.Model',
    fields: [
        'id', 'name'
    ],

    hasMany: 'OrderItem'
});

next, I define a tree store and a tree panel (for some selected fields):

    var store = Ext.create('Ext.data.TreeStore', {
        model: 'User',
        autoLoad: true,
        autoSync: true,
     root: {
        name: "Root node",
        id: '0',
        expanded: true
    }, 
   sorters: [{
        property: 'id',
        direction: 'ASC' // DESC
    }]
});

var tree = Ext.create('Ext.tree.Panel', {
        store: store,  
    displayField: 'name', // what nodes display (default->text)
        columns: [{
        xtype: 'treecolumn',
        text: 'name',
        dataIndex: 'name',
        width: 150,
        sortable: true
    }, {
        text: 'total',
        dataIndex: 'total',
    width: 150,
        flex: 1,
        sortable: true
    }, {
        text: 'price',
        dataIndex: 'price',
    width: 50,
        flex: 1,
        sortable: true
    },{ 
        text: 'quantity',
        dataIndex: 'quantity',
    width: 150,
        flex: 1
    }, {
        text: 'id',
        dataIndex: 'id',
        flex: 1,
        width: 15,
        sortable: true
    }],
        collapsible: true,
        viewConfig: {
            plugins: {
                ptype: 'treeviewdragdrop',  // see Ext.tree.plugin.TreeViewDragDrop
                nodeHighlightColor : '7B68EE',
        nodeHighlightOnDrop : true, 
        nodeHighlightOnRepair: true, 
        enableDrag: true, 
        enableDrop: true
            }
       },
        renderTo: 'tree-div',
        height: 300,
        width: 900,
        title: 'Items',
        useArrows: true,
        dockedItems: [{
            xtype: 'toolbar',
            items: [{
                text: 'Expand All',
                handler: function(){
                    tree.expandAll();
                }
            }, {
                text: 'Collapse All',
                handler: function(){
                    tree.collapseAll();
                }
            }]
        }]
    });
});

I see the panel, the root and the first level users (as subnodes of the root). I do not see any subnodes (orders, order_items and so on).

I looked carefully at a number of posts, improved things quite a lot, but still miss to get a working solution.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猛虎独行 2024-12-14 11:22:29

我面临着同样的任务,首先很高兴遇到你的帖子!
经过 5 个小时探索与之相关的官方文档:

我能够什么都不填充我的嵌套树存储比这个更好:(

在我的例子中,主要模型是 Camgroup,它有许多相机作为“cams”:它允许为每个组使用 .cams())

Ext.define('AV.store.sCamgroups', {
    extend: 'Ext.data.TreeStore',
    model: 'AV.model.Camgroup',
    autoLoad: true,
    root: {
        expanded: true,
        text: "Grouped Cameras"
    },
    proxy: {
        type: 'ajax',
        url: 'data/camgroups.json',
        reader: {
            type: 'json',
            root: 'camgroups',
            successProperty: 'success'
        }
    },
    listeners: {
        load: function(thisStore, rootnode, records, successful, eOpts){
            records.forEach(function(group){
                group.cams().each(function(cam) {
                    group.appendChild({
                        text: cam.get('name'),
                        leaf: true
                    });
                });
            });
        }
    }
});

camgroups.json 返回这样的东西:

{
    success: true,
    camgroups: [{
        "id"    : "group1",
        "name"  : "Exterior cams",
        "cams"  : [{
            "id"    : "cam3",
            "name"  : "Camera three",
            "url"   : "...",
            "img"   : "images/cams/3.png",
            "ratio" : 1.33
        },{
            "id"    : "cam4",
            "name"  : "Camera four",
            "url"   : "...",
            "img"   : "images/cams/4.png",
            "ratio" : 1.33
        }]
    }]
}

希望这会帮助你,尽管继续寻找更好的解决方案(定义合适的读者的问题)。

再次,在“Ext.data.reader.Reader”中,我可以看到 Reader 有配置属性“implicitInincludes”,该属性应该“自动解析响应对象中其他模型中嵌套的模型”,但我无法使其工作 =(

干杯,
伊利亚

I am facing the same task, and first was glad to run into your post!
After 5 hours of exploring the official docs regarding to it:

I was able to populate my nested treestore with nothing better than this:

(in my case the main model is Camgroup which hasMany Camera as 'cams': which allows to use .cams() for every group)

Ext.define('AV.store.sCamgroups', {
    extend: 'Ext.data.TreeStore',
    model: 'AV.model.Camgroup',
    autoLoad: true,
    root: {
        expanded: true,
        text: "Grouped Cameras"
    },
    proxy: {
        type: 'ajax',
        url: 'data/camgroups.json',
        reader: {
            type: 'json',
            root: 'camgroups',
            successProperty: 'success'
        }
    },
    listeners: {
        load: function(thisStore, rootnode, records, successful, eOpts){
            records.forEach(function(group){
                group.cams().each(function(cam) {
                    group.appendChild({
                        text: cam.get('name'),
                        leaf: true
                    });
                });
            });
        }
    }
});

camgroups.json returns smth like this:

{
    success: true,
    camgroups: [{
        "id"    : "group1",
        "name"  : "Exterior cams",
        "cams"  : [{
            "id"    : "cam3",
            "name"  : "Camera three",
            "url"   : "...",
            "img"   : "images/cams/3.png",
            "ratio" : 1.33
        },{
            "id"    : "cam4",
            "name"  : "Camera four",
            "url"   : "...",
            "img"   : "images/cams/4.png",
            "ratio" : 1.33
        }]
    }]
}

Hope this will help you though keep looking for a better solution (prob defining a proper reader).

Again, in "Ext.data.reader.Reader" I can see that Reader has config property 'implicitIncludes' which is supposed 'to automatically parse models nested within other models in a response object', but I cannot make it working =(

Cheers,
Ilya

烟雨凡馨 2024-12-14 11:22:29

进一步进步。
请参阅
http://www.sencha.com/forum/showthread.php?153986-Empty-column-something-I-can-t-get-with-Ext.data.TreeStore-and-or- Ext.tree.Panel

我感谢任何进一步的建议。


我取得了一些进步。看来我需要修改我的 json:

{
"children": [      <<<<---- use the same string to insert nested data, see below too
    {
        "id": 12,
        "name": "Ed2",
    "children": []   <<<<---- need this line, otherwise, JS tries to load subnodes for ever
},
    {
        "id": 123,
        "name": "Ed",
        "children": [    <<<<---- as above
            {
                "id": 50,
                "total": 100,
                "info" : "hello",
        "name" : "ciao",
                "children": [         <<<<---- as above
                    {
                        "id"      : 20,
                        "price"   : 40,
                        "quantity": 2,
                        "children" : {         <<<<---- as above
                            "id": 1000,
                            "name": "MacBook Pro",
            "children": []        <<<<---- as above bis
                        }
                    },
                    {
                        "id"      : 21,
                        "price"   : 20,
                        "quantity": 3,
                        "children" : {   <<<<---- as above
                            "id": 1001,
                            "name": "iPhone",
            "children": []     <<<<---- as above bis
                        }
                    }
                ]
            }
        ]
    }
]

}

然后模型的以下定义有效:

Ext.define("User", {
extend: 'Ext.data.Model',
fields: [
    'id', 'name', 'info', 'price', 'quantity', 'order_id', 'product_id'
],

proxy: {
    type: 'ajax',  //rest
    url : 'ex1.json',
    reader: {
        type: 'json',
        root: 'children'
    }
}

});

因此,似乎根本不需要不同级别的嵌套数据的模型之间的关联。

它有效,尽管我不确定是否有缺点。
我仍在寻求你的建议,我通过尝试和错误,我还没有看到潜在的逻辑。
谢谢。


我有新的想法。使用唯一字符串“children”的技巧似乎不太好。
让我考虑一个非常简单的 json:

{
"users": [
    {
        "id": 12,
        "name": "Ed2",
    "orders": []
},
    {
        "id": 123,
        "name": "Ed",
        "orders": [
            {
                "id": 50,
                "info" : "hello",
        "name" : "MM",
                "leaf" : 'true',
                "some_else": []    
               }]
     }
        ]

}

我希望得到的 extJS 树是:

Root
|--ED
|--ED2 
   |--MM

模型只是

Ext.define("User", {
    extend: 'Ext.data.Model',
    fields: [
        'id', 'name'
    ],

    hasMany: {model: 'Order', name: 'orders'},

    proxy: {
        type: 'ajax',  //rest
        url : 'my_file.json',
        reader: {
            type: 'json',
            root: 'users'
        }
    }
});

Ext.define("Order", {
    extend: 'Ext.data.Model',
    fields: [
        'id', 'name', 'info' 
    ],
    belongsTo: 'User'
});

我得到的最终输出只是:

Root
|--ED
|--ED2 

这是我的错误,还是缺少功能?有没有办法不改变我的json?

多谢

Further progress.
Please see at
http://www.sencha.com/forum/showthread.php?153986-Empty-column-something-I-can-t-get-with-Ext.data.TreeStore-and-or-Ext.tree.Panel

I appreciate any further advise.


I made some progress. It seems I need to modify my json:

{
"children": [      <<<<---- use the same string to insert nested data, see below too
    {
        "id": 12,
        "name": "Ed2",
    "children": []   <<<<---- need this line, otherwise, JS tries to load subnodes for ever
},
    {
        "id": 123,
        "name": "Ed",
        "children": [    <<<<---- as above
            {
                "id": 50,
                "total": 100,
                "info" : "hello",
        "name" : "ciao",
                "children": [         <<<<---- as above
                    {
                        "id"      : 20,
                        "price"   : 40,
                        "quantity": 2,
                        "children" : {         <<<<---- as above
                            "id": 1000,
                            "name": "MacBook Pro",
            "children": []        <<<<---- as above bis
                        }
                    },
                    {
                        "id"      : 21,
                        "price"   : 20,
                        "quantity": 3,
                        "children" : {   <<<<---- as above
                            "id": 1001,
                            "name": "iPhone",
            "children": []     <<<<---- as above bis
                        }
                    }
                ]
            }
        ]
    }
]

}

Then the following definition of a model works:

Ext.define("User", {
extend: 'Ext.data.Model',
fields: [
    'id', 'name', 'info', 'price', 'quantity', 'order_id', 'product_id'
],

proxy: {
    type: 'ajax',  //rest
    url : 'ex1.json',
    reader: {
        type: 'json',
        root: 'children'
    }
}

});

So, it seems that associations among models for the different levels of my nested data are not needed at all.

It works, although I am not sure whether there are drawbacks or not.
I am still looking for your advise, I go by try&mistake, I do not see the underlying logic yet.
Thks.


I have second thoughts. The trick to use a unique string 'children' does not seem so good.
Let me consider a very simple json:

{
"users": [
    {
        "id": 12,
        "name": "Ed2",
    "orders": []
},
    {
        "id": 123,
        "name": "Ed",
        "orders": [
            {
                "id": 50,
                "info" : "hello",
        "name" : "MM",
                "leaf" : 'true',
                "some_else": []    
               }]
     }
        ]

}

The extJS tree I wish to get is:

Root
|--ED
|--ED2 
   |--MM

The model is just

Ext.define("User", {
    extend: 'Ext.data.Model',
    fields: [
        'id', 'name'
    ],

    hasMany: {model: 'Order', name: 'orders'},

    proxy: {
        type: 'ajax',  //rest
        url : 'my_file.json',
        reader: {
            type: 'json',
            root: 'users'
        }
    }
});

Ext.define("Order", {
    extend: 'Ext.data.Model',
    fields: [
        'id', 'name', 'info' 
    ],
    belongsTo: 'User'
});

The final output I get is just:

Root
|--ED
|--ED2 

is it a mistake of mine, or a missing feature? is there a way out without to change my json?

Thanks a lot

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文