PDA

View Full Version : Adding node to a treestore doesn't use Model



sissonb
4 Sep 2012, 2:17 PM
I have the following store/model

Ext.define('app.store.Scripts', {
extend:'Ext.data.TreeStore',
model:"app.model.Script",
proxy:{
type:'memory',
reader:{
type:'json',
root:""
}
}
});



Ext.define('app.model.Script', {
extend: 'Ext.data.Model',
fields: [
{
name: 'scriptId',
type: 'string'
},
{
name: 'appId',
type: 'string'
},
{
name: 'text',
mapping:'title',
type: 'string'
},
{
name: 'questionId',
type: 'string'
},
{
name: 'lastQuestion',
type: 'string'
},
{
name: 'kind',
type: 'string'
}
]
});

When I first set the root node, the data gets mapped to the model and everything works fine,


this.getScriptsStore().setRootNode({
expanded:true,
children:[{
title:"This will map to text"
}]
});



I have an `itemexpand` listener in my treepanel. One of the parameters given to me is a `Ext.data.NodeInterface`. I am trying to add a child to this NodeInterface and have it use my Model, but I'm failing.


node.appendChild({
title:"This will NOT map to text, but will add node to tree"
});


node.appendChild({
text:"This will add a new node with text"
});


How do I add a child to a node in a tree and have it use the defined model for the store?

Thanks!

vietits
4 Sep 2012, 6:57 PM
Try to use convert() instead of mapping.


fields: [{
name: 'text',
convert: function(v, rec){
return rec.raw.title;
},
....
}]

sissonb
5 Sep 2012, 8:36 AM
Thanks for the suggestion, but no luck.

Another thing I've noticed is that the children attribute maps to the model, but the root does not.



node.appendChild({
title:"This will NOT map to text, but will add node to tree",
children:[
{
title:"This WILL map to text and will add node to tree"
}
]
});

sissonb
5 Sep 2012, 11:44 AM
Since this issue exists I was thinking about explicitly using my model before adding the data to the node. It looks like my model could be messed up though. I get the following when I try to use my model.


var model = Ext.create("app.model.Script",{title:"title",scriptId:"Works"});
model.get("text"); //returns undefined
model.get("title"); //returns undefined
model.get("scriptId"); //returns "Works"


What is the correct way to use my model?

Thanks!

vietits
5 Sep 2012, 5:37 PM
Field mapping is available for data reader only while convert() is available each time you set value to that field.

When you call <node>.appendChild() and supply its with nested data, then the following will happen:
1. The top most data will be used to construct a new node by using the respective model. This does not involve the data reader so field mapping will be ignored.

2. On node added, TreeStore will use its proxy data reader to extract all children of this node and at this period, field mapping has effect because data reader will use field mapping in extracting data.

3. With extracted data, TreeStore will call its fillNode() to append respective nodes to the node created in step 1 above.

This process will continue till to the lowest level of data.

Below is my example that using convert() instead of mapping.


Ext.onReady(function(){
Ext.define('TreeNode', {
extend: 'Ext.data.Model',
fields: [{
name: 'text', convert: function(v, r){ return r.raw.title; }
}]
});

var store = Ext.create('Ext.data.TreeStore', {
model: 'TreeNode',
proxy: 'memory',
root: {
title: 'Root',
expand: true
}
});


var tree = Ext.create('Ext.tree.Panel', {
renderTo: Ext.getBody(),
width: 400,
height: 400,
store: store,
tbar: {
items: [{
text: 'Add nodes',
handler: function(){
var node = tree.getSelectionModel().getSelection()[0] || tree.getRootNode();
if(node && !node.leaf){
var random = Ext.id();
node.expand();
node.appendChild({
title: 'Node ' + random,
children: [{
title: 'Node ' + random + ' 1'
},{
title: 'Node ' + random + ' 2',
leaf: true
}]
});
}
}
}]
}
});
});

sissonb
5 Sep 2012, 6:11 PM
Hey vietits, I tried out your sample and it seems to have the same issues. Here's a screencast.

http://screencast.com/t/7yVRAv1IPgVQ

vietits
5 Sep 2012, 6:28 PM
It's strange! I have tested my example with Ext 4.1.1 both on Chrome and Firefox and it works well.

sissonb
5 Sep 2012, 6:39 PM
So I downloaded the latest Ext JS and the issue is fixed. Thanks for all the help.

My old version was
Build date: 2012-04-20 14:10:47 (19f55ab932145a3443b228045fa80950dfeaf9cc)

wared
22 Oct 2013, 7:07 AM
Try to use convert() instead of mapping.


fields: [{
name: 'text',
convert: function(v, rec){
return rec.raw.title;
},
....
}]


I had a similar problem defining the root node in the tree store's config. Indeed, in this case, mapping seems to be ignored. I have fixed this issue using vietits solution but I haven't investigated deeper. Let me know if you need additional informations, I'll try to give you more details and some code. Version 4.2.1.883.