【问题标题】:How do I show nested data into a tree?如何将嵌套数据显示到树中?
【发布时间】:2011-10-03 07:53:22
【问题描述】:

进一步的进展。请参阅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();
                }
            }]
        }]
    });
});

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

我仔细查看了一些帖子,改进了很多,但仍然错过了一个可行的解决方案。

【问题讨论】:

    标签: javascript extjs tree nested


    【解决方案1】:

    我面临同样的任务,首先很高兴遇到你的帖子! 经过 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 具有配置属性“implicitIncludes”,它应该“自动解析嵌套在响应对象中的其他模型中的模型”,但我无法使其工作=(

    干杯, 伊利亚

    【讨论】:

      【解决方案2】:

      进一步的进展。 请参阅 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?

      非常感谢

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-14
        • 1970-01-01
        • 2021-10-31
        • 1970-01-01
        • 2022-11-08
        • 2019-12-24
        • 1970-01-01
        • 2021-09-03
        相关资源
        最近更新 更多