javascript 如何将嵌套数据显示到树中?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7632363/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I show nested data into a tree?
提问by mario
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
我正在尝试开发一个简单的 extJS Ext 4.0.2a 脚本,以将一些嵌套数据显示为拖放树。为了尝试,我使用了http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.reader.Reader 中的一个简单示例
Data are given as a users.json file:
数据作为 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"
}
}
]
}
]
}
]
}
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.
我仔细查看了一些帖子,改进了很多,但仍然没有找到可行的解决方案。
回答by ilyavf
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:
我面临着同样的任务,首先很高兴遇到你的帖子!经过 5 个小时的探索官方文档后:
- http://docs.sencha.com/ext-js/4-0/#!/guide/data
- http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.reader.Reader
- http://docs.sencha.com/ext-js/4-0/#!/guide/data
- http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.reader.Reader
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)
(在我的例子中,主要模型是 Camgroup,其中有许多相机作为“凸轮”:它允许对每个组使用 .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 returns smth like this:
camgroups.json 像这样返回 smth:
{
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 =(
同样,在“Ext.data.reader.Reader”中,我可以看到 Reader 具有配置属性“implicitIncludes”,该属性应该“自动解析嵌套在响应对象中其他模型中的模型”,但我无法使其工作=(
Cheers, Ilya
干杯,伊利亚
回答by mario
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:
我取得了一些进展。看来我需要修改我的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:
我有第二个想法。使用唯一字符串 'children' 的技巧似乎不太好。让我考虑一个非常简单的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:
我希望得到的 extJS 树是:
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?
这是我的错误还是缺失的功能?有没有办法不改变我的json?
Thanks a lot
非常感谢