【问题标题】:Correct JSON and Model with TreeStore and TreePanel使用 TreeStore 和 TreePanel 更正 JSON 和模型
【发布时间】:2012-08-01 16:31:13
【问题描述】:

我有一个来自服务器端的 JSON 字符串:

{"success":"true","total":"6","list":
  [{"id":"1","name":"folder1","parentid":"null","type":"0"},
   {"id":"2","name":"r1","parentid":"1","type":"1"},
   {"id":"3","name":"folder2","parentid":"1","type":"0"},
   {"id":"4","name":"r2","parentid":"3","type":"1"},
   {"id":"5","name":"r3","parentid":"null","type":"1"},
   {"id":"6","name":"folder3","parentid":"null","type":"0"}]}

如何把它变成一棵树?谁能建议我如何获取列表中的元素(id、name、parentid、type)?

【问题讨论】:

    标签: javascript extjs4.1


    【解决方案1】:

    我使用了以下结构:

    型号

    Ext.define('MyApp.model.MyTreeModel', {
        extend: 'Ext.data.Model',
        fields: [
             'someStringIdentifier',
             'children',
             'dataForThisNode',
        ],
    });
    

    商店

    Ext.define('MyApp.store.MyTreeStore', {
        extend: 'Ext.data.TreeStore',
        model: 'MyApp.model.MyTreeModel',
        storeId: 'cubeDynamicStoreId',
        autoLoad: false,
    
        proxy: {
            type: 'ajax',
            api: {
                read : '/myapp/rest/myquery',
            },
            reader: {
                type: 'json',
                root: 'children',
                successProperty: 'success',
                idProperty: 'id',
            },
        },
    
        // bug in extjs4.1 autoLoad is ignored
        // specifying "loaded: true" resolves the problem
        root: {
            expanded: true,
            loaded: true,
        },
    });
    

    示例 JSON(使用 http://jsonviewer.stack.hu/ 进行可视化)

    使用叶子属性在任何节点停止扩展

    {"children":{"leaf":false,"someStringIdentifier":"Total","dataForThisNode":{},"children":[{"leaf":true,"someStringIdentifier":"data1","dataForThisNode":{},"children":[{"leaf":false,"someStringIdentifier":"2012","dataForThisNode":{},"children":null},{"leaf":false,"someStringIdentifier":"2013","dataForThisNode":{},"children":null},{"leaf":false,"someStringIdentifier":"2014","dataForThisNode":{},"children":null},{"leaf":false,"someStringIdentifier":"2015","dataForThisNode":{},"children":null},{"leaf":false,"someStringIdentifier":"2016","dataForThisNode":{},"children":null},{"leaf":false,"someStringIdentifier":"2017","dataForThisNode":{},"children":null},{"leaf":false,"someStringIdentifier":"2018","dataForThisNode":{},"children":null}]},{"leaf":true,"someStringIdentifier":"data2","dataForThisNode":{},"children":[{"leaf":false,"someStringIdentifier":"2012","dataForThisNode":{},"children":null},{"leaf":false,"someStringIdentifier":"2013","dataForThisNode":{},"children":null},{"leaf":false,"someStringIdentifier":"2014","dataForThisNode":{},"children":null},{"leaf":false,"someStringIdentifier":"2015","dataForThisNode":{},"children":null},{"leaf":false,"someStringIdentifier":"2016","dataForThisNode":{},"children":null},{"leaf":false,"someStringIdentifier":"2017","dataForThisNode":{},"children":null},{"leaf":false,"someStringIdentifier":"2018","dataForThisNode":{},"children":null}]}]},"success":true}
    

    【讨论】:

    • 没有错误。如果您设置 autoLoad:false 然后执行 expanded: true 那么您将从树中获得负载。
    【解决方案2】:

    让我们从商店定义开始:

    Ext.define('app.store.Tasks', {
    
        extend: 'Ext.data.TreeStore',    
        model:  'app.model.Task',
    
        autoSync: true,
        autoLoad: true,
    
        root: {
            text: 'Root',
            id: 'NULL',
            expanded: true
        },
    });
    

    需要注意的重要一点是,我们在这里扩展了TreeStore。因此,我们的模型记录将使用 Ext.data.NodeInterface 包装,其中包括许多与树相关的字段(例如,parentNode)。

    然后到模型定义:

    Ext.define('app.model.Task', {
        extend: 'Ext.data.Model',
        fields: [
            {name: 'name'     , type: 'string'},
    
            {name: 'iconCls'  , type: 'string', defaultValue: 'treenode-no-icon'},
            {name: 'expanded' , type: 'boolean', defaultValue: true, persist: false},
            {name: 'index'     , type: 'int'},        
        ],
    
        proxy: {
            type: 'direct',
    
            api: {
                create:  Tasks.Create,
                read:    Tasks.Read,
                update:  Tasks.Update,
                destroy: Tasks.Destroy,
            },
        },
    
    });
    

    我们定义的唯一“真实”字段是name,所有其他字段都是NodeInterface 的一部分:iconCls 的默认值为无图标; expanded 设置为persist:false,因此折叠/展开节点不会导致更新服务器调用; index 包含在内,因此如果用户重新排序节点(使用拖放),将进行服务器调用。

    请注意,没有 id 字段,因为模型的默认 idPropertyid,ExtJS 足够聪明,可以判断如果您的 JSON 中有 id 字段 - 它代表记录的唯一 ID。

    另请注意,没有 parentId 字段 - 通过提供正确的 JSON(节点具有 children 属性),NodeInterface 计算出每个节点的正确 parentNode

    然后是 JSON:

    {
        "success":true,
        "children":[
         {
            "id":"1",
            "name":"Home",
            "children":[
               {
                  "id":"6",
                  "name":"Emails",
                  "leaf":true
               },
               {
                  "id":"7",
                  "name":"Bath",
                  "leaf":true
               }
            ],
            "leaf":false
         },         
        ]
    }
    

    差不多就是这样!

    【讨论】:

    • 你能在你的例子中解释更多关于代理的api吗?我不知道..
    • 方便远程服务器上的CRUD操作。 Docsthis 你可能也会感兴趣。
    • 我可以使用 ajax 代理类型本身对吗?就像我在问题中给出的那样?
    • 当然。您可以选择 Ajax 或 Direct - 最适合您的。
    • 我已经改变了我的.. 但是当访问子节点时我仍然收到相同的错误Uncaught TypeError: Cannot read property 'internalId' of undefined.. 第一级节点也是可见的但没有任何文本.. 我错过了什么吗?
    【解决方案3】:

    Izhaki 对这个主题的第一个回答很好,但它似乎具有误导性,并且如果您期望看到节点的描述,它就不会按原样工作。我花了几个小时来解决这个问题。查看此描述的唯一方法是将“名称”重命名为“文本”。见下文。

    Ext.define('app.model.Task', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'text'     , type: 'string'},
    
        {name: 'iconCls'  , type: 'string', defaultValue: 'treenode-no-icon'},
        {name: 'expanded' , type: 'boolean', defaultValue: true, persist: false},
        {name: 'index'     , type: 'int'},        
    ],
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-09
      • 2015-07-04
      • 1970-01-01
      • 2014-06-08
      • 1970-01-01
      相关资源
      最近更新 更多