PDA

View Full Version : Mixing the loading tree node children all at once AND dynamically.



FoxMulder900
13 Aug 2012, 6:14 AM
Has anyone else ran into a situation where they would like to initially load some nodes and their children into a tree, but still allow those children to load dynamically?

Basically what I have is an alphabetically organized tree, so the root has children that look something like this


[
{text: 'A', children: [{text: 'Aardvark'},{text: 'Ant'}], expanded:true},
{text: 'B', children: [{text: 'Bat'},{text: 'Bear'}], expanded:true},
{text: 'C', children: [{text: 'Cat'},{text: 'Chicken'}], expanded:true}
]

What happens here is that an additional request is sent for each letter (A,B,C) instead of showing the children which are already defined.

What I want is to have 1 initial request (instead of one for each letter of the alphabet) to load my basic structure but still allow individual requests to be made when the user expands any of the children.

Hopefully I have made my scenario clear enough, any ideas are appreciated!

redraid
13 Aug 2012, 6:29 AM
afteritemexpand: function (node) {
this.getStore().load({
node: node
});
}

FoxMulder900
13 Aug 2012, 7:58 AM
Thanks for the reply, but it actually seems to have that functionality by default. What I really need is to be able to stop any node that already has children from trying to load them from the server.

If a node has children already defined: expand and show the defined children
Otherwise: continue with ajax call to request children.

vietits
13 Aug 2012, 6:18 PM
I think what you require is default behaviour of TreePanel. Below is an example showing that behaviour. When I run this example with Ext 4.1.1 and Chrome 20, only clicking on C node will send request to load its children, while clicking on A or B node will not send loading request but showing its existing children instead.


Ext.onReady(function() {
Ext.Ajax.on('beforerequest', function(connection, options){
console.log('request', options)
});


var store = Ext.create('Ext.data.TreeStore', {
fields: ['text'],
proxy: {
type: 'ajax',
url: 'treegrid.json'
},
root: {}
});


var tree = Ext.create('Ext.tree.Panel', {
renderTo: Ext.getBody(),
title: 'Tree Demo',
width: 200,
height: 300,
rootVisible: false,
store: store,
columns: [{
xtype: 'treecolumn',
text: 'Text',
flex: 1,
dataIndex: 'text'
}]
});
});

treegrid.json


[{
text: 'A',
expanded:false,
children: [{
text: 'Aardvark',
leaf: true
},{
text: 'Ant',
leaf: true
}]
},{
text: 'B',
expanded:true,
children: [{
text: 'Bat',
leaf: true
},{
text: 'Bear',
leaf: true
}]
},{
text: 'C'
}]

FoxMulder900
14 Aug 2012, 6:20 AM
You are right, that is exactly what I need! Based on your working example I was able to pinpoint my problem to the root configuration in my reader.

My json is actually coming back nested, similar to this:


{
payload: [{
text: 'A',
expanded:false,
children: [{
text: 'Aardvark',
leaf: true
},{
text: 'Ant',
leaf: true
}]
},{
text: 'B',
expanded:true,
children: [{
text: 'Bat',
leaf: true
},{
text: 'Bear',
leaf: true
}]
},{
text: 'C'
}]
}


My reader is configured like this, but I don't understand what I am doing incorrectly.


Ext.onReady(function() {
Ext.Ajax.on('beforerequest', function(connection, options){
console.log('request', options)
});

var store = Ext.create('Ext.data.TreeStore', {
fields: ['text'],
proxy: {
type: 'ajax',
url: 'treegrid.json',
reader: {
type: 'json',
root: 'payload'
}
},
root: {}
});

var tree = Ext.create('Ext.tree.Panel', {
renderTo: Ext.getBody(),
title: 'Tree Demo',
width: 200,
height: 300,
rootVisible: false,
store: store,
columns: [{
xtype: 'treecolumn',
text: 'Text',
flex: 1,
dataIndex: 'text'
}]
});
});


Thanks a lot for your help!

vietits
14 Aug 2012, 3:35 PM
Your problem is that you config your data root with 'payload' while your json data used 'children' for sub-node data. They must be the same. So try to replace 'payload' with 'children' or vice versa. Example:
1. JSON


{
//payload: [{
children: [{
text: 'A',
expanded:false,
children: [{ <- change this to 'payload' if you config root: 'payload'
text: 'Aardvark',
leaf: true
},{
text: 'Ant',
leaf: true
}]
},{
text: 'B',
expanded:true,
children: [{ <- change this to 'payload' if you config root: 'payload'
text: 'Bat',
leaf: true
},{
text: 'Bear',
leaf: true
}]
},{
text: 'C'
}]
}

2. Code


...
var store = Ext.create('Ext.data.TreeStore', {
fields: ['text'],
proxy: {
type: 'ajax',
url: 'treegrid.json',
reader: {
type: 'json',
// root: 'payload'
root: 'children' <- children is default so you can ommit it
}
},
root: {}
});