I have a JSON String es from the server side:
{"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"}]}
How do I turn that into a tree? Can anyone suggest me how to get the elements in the list (id, name, parentid, type)?
I have a JSON String es from the server side:
{"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"}]}
How do I turn that into a tree? Can anyone suggest me how to get the elements in the list (id, name, parentid, type)?
Share Improve this question edited Aug 1, 2012 at 17:29 istruble 13.7k2 gold badges50 silver badges53 bronze badges asked Aug 1, 2012 at 16:31 user1567829user1567829 311 gold badge1 silver badge4 bronze badges3 Answers
Reset to default 3I used the following structure:
Model
Ext.define('MyApp.model.MyTreeModel', {
extend: 'Ext.data.Model',
fields: [
'someStringIdentifier',
'children',
'dataForThisNode',
],
});
Store
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,
},
});
Sample JSON ( use http://jsonviewer.stack.hu/ to visualize)
Use the leaf property to stop expansion at any node
{"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}
Let's start with the store definition:
Ext.define('app.store.Tasks', {
extend: 'Ext.data.TreeStore',
model: 'app.model.Task',
autoSync: true,
autoLoad: true,
root: {
text: 'Root',
id: 'NULL',
expanded: true
},
});
The important thing to note is that we are extending TreeStore
here. Thus, our model records will be wrapped with Ext.data.NodeInterface
, which included many tree-related fields (like, for example, parentNode
).
Then to the model definition:
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,
},
},
});
The only 'real' field we've defined is name
, All the others are part of NodeInterface
: iconCls
has a default value of no icon; expanded
is set with persist:false
so collapsing/expanding a node won't result in an update server call; index
is included so if the user re-order nodes (using drag and drop) server calls will be made.
Notice that there's no id
field since a a model's default idProperty
is id
, ExtJS is smart enough to figure that if your JSON has id
field in it - it represents the unique id of the record.
Also note there's no parentId
field - by providing correct JSON (with nodes having children
property), NodeInterface
work out the correct parentNode
of each node.
Then the JSON:
{
"success":true,
"children":[
{
"id":"1",
"name":"Home",
"children":[
{
"id":"6",
"name":"Emails",
"leaf":true
},
{
"id":"7",
"name":"Bath",
"leaf":true
}
],
"leaf":false
},
]
}
That's pretty much it!
The first answer on this subject from Izhaki is great, but it seems misleading and will not work as is if your expectation is to see the description for nodes. I spent several hours struggling with this. The only way to see this description is to rename "name" with "text". see below.
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'},
],