使用 TreeStore 和 TreePanel 更正 JSON 和模型
Posted
技术标签:
【中文标题】使用 TreeStore 和 TreePanel 更正 JSON 和模型【英文标题】:Correct JSON and Model with TreeStore and TreePanel 【发布时间】: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)?
【问题讨论】:
【参考方案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
字段,因为模型的默认 idProperty
是 id
,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操作。 Docs。 this 你可能也会感兴趣。 我可以使用 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',
],
【讨论】:
以上是关于使用 TreeStore 和 TreePanel 更正 JSON 和模型的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Extjs 4.0.7 TreeStore 会自动调用 http delete 方法?