9

Further progress. Please see at http://www.sencha.com/forum/showthread.php?153986-Empty-column-something-I-can-t-get-with-Ext.data.TreeStore-and-or-Ext.tree.Panel

I always appreciate any further advise.


I am trying to develop a simple extJS Ext 4.0.2a script to display some nested data as a Drag&Drop tree. To try, I use a simple example from http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.reader.Reader

Data are given as a users.json file:

{ "users": [ { "id": 123, "name": "Ed", "orders": [ { "id": 50, "total": 100, "order_items": [ { "id" : 20, "price" : 40, "quantity": 2, "product" : { "id": 1000, "name": "MacBook Pro" } }, { "id" : 21, "price" : 20, "quantity": 3, "product" : { "id": 1001, "name": "iPhone" } } ] } ] } ] } 

I wish to display data as a tree, whose first level nodes are users, second level nodes are orders, and so on.

From the same doc, I learn how to define my models (I believe):

 Ext.define("User", { extend: 'Ext.data.Model', fields: [ 'id', 'name' ], hasMany: {model: 'Order', name: 'orders'}, proxy: { type: 'ajax', // rest url : 'users.json', reader: { type: 'json', root: 'users' } } }) ; Ext.define("Order", { extend: 'Ext.data.Model', fields: [ 'id', 'total' ], hasMany : {model: 'OrderItem', name: 'orderItems', associationKey: 'order_items'}, belongsTo: 'User' }); Ext.define("OrderItem", { extend: 'Ext.data.Model', fields: [ 'id', 'price', 'quantity', 'order_id', 'product_id' ], belongsTo: ['Order', {model: 'Product', associationKey: 'product'}] }); Ext.define("Product", { extend: 'Ext.data.Model', fields: [ 'id', 'name' ], hasMany: 'OrderItem' }); 

next, I define a tree store and a tree panel (for some selected fields):

 var store = Ext.create('Ext.data.TreeStore', { model: 'User', autoLoad: true, autoSync: true, root: { name: "Root node", id: '0', expanded: true }, sorters: [{ property: 'id', direction: 'ASC' // DESC }] }); var tree = Ext.create('Ext.tree.Panel', { store: store, displayField: 'name', // what nodes display (default->text) columns: [{ xtype: 'treecolumn', text: 'name', dataIndex: 'name', width: 150, sortable: true }, { text: 'total', dataIndex: 'total', width: 150, flex: 1, sortable: true }, { text: 'price', dataIndex: 'price', width: 50, flex: 1, sortable: true },{ text: 'quantity', dataIndex: 'quantity', width: 150, flex: 1 }, { text: 'id', dataIndex: 'id', flex: 1, width: 15, sortable: true }], collapsible: true, viewConfig: { plugins: { ptype: 'treeviewdragdrop', // see Ext.tree.plugin.TreeViewDragDrop nodeHighlightColor : '7B68EE', nodeHighlightOnDrop : true, nodeHighlightOnRepair: true, enableDrag: true, enableDrop: true } }, renderTo: 'tree-div', height: 300, width: 900, title: 'Items', useArrows: true, dockedItems: [{ xtype: 'toolbar', items: [{ text: 'Expand All', handler: function(){ tree.expandAll(); } }, { text: 'Collapse All', handler: function(){ tree.collapseAll(); } }] }] }); }); 

I see the panel, the root and the first level users (as subnodes of the root). I do not see any subnodes (orders, order_items and so on).

I looked carefully at a number of posts, improved things quite a lot, but still miss to get a working solution.

2 Answers 2

4

I am facing the same task, and first was glad to run into your post! After 5 hours of exploring the official docs regarding to it:

I was able to populate my nested treestore with nothing better than this:

(in my case the main model is Camgroup which hasMany Camera as 'cams': which allows to use .cams() for every group)

Ext.define('AV.store.sCamgroups', { extend: 'Ext.data.TreeStore', model: 'AV.model.Camgroup', autoLoad: true, root: { expanded: true, text: "Grouped Cameras" }, proxy: { type: 'ajax', url: 'data/camgroups.json', reader: { type: 'json', root: 'camgroups', successProperty: 'success' } }, listeners: { load: function(thisStore, rootnode, records, successful, eOpts){ records.forEach(function(group){ group.cams().each(function(cam) { group.appendChild({ text: cam.get('name'), leaf: true }); }); }); } } }); 

camgroups.json returns smth like this:

{ success: true, camgroups: [{ "id" : "group1", "name" : "Exterior cams", "cams" : [{ "id" : "cam3", "name" : "Camera three", "url" : "...", "img" : "images/cams/3.png", "ratio" : 1.33 },{ "id" : "cam4", "name" : "Camera four", "url" : "...", "img" : "images/cams/4.png", "ratio" : 1.33 }] }] } 

Hope this will help you though keep looking for a better solution (prob defining a proper reader).

Again, in "Ext.data.reader.Reader" I can see that Reader has config property 'implicitIncludes' which is supposed 'to automatically parse models nested within other models in a response object', but I cannot make it working =(

Cheers, Ilya

Sign up to request clarification or add additional context in comments.

Comments

1

Further progress. Please see at http://www.sencha.com/forum/showthread.php?153986-Empty-column-something-I-can-t-get-with-Ext.data.TreeStore-and-or-Ext.tree.Panel

I appreciate any further advise.


I made some progress. It seems I need to modify my json:

{ "children": [ <<<<---- use the same string to insert nested data, see below too { "id": 12, "name": "Ed2", "children": [] <<<<---- need this line, otherwise, JS tries to load subnodes for ever }, { "id": 123, "name": "Ed", "children": [ <<<<---- as above { "id": 50, "total": 100, "info" : "hello", "name" : "ciao", "children": [ <<<<---- as above { "id" : 20, "price" : 40, "quantity": 2, "children" : { <<<<---- as above "id": 1000, "name": "MacBook Pro", "children": [] <<<<---- as above bis } }, { "id" : 21, "price" : 20, "quantity": 3, "children" : { <<<<---- as above "id": 1001, "name": "iPhone", "children": [] <<<<---- as above bis } } ] } ] } ] 

}

Then the following definition of a model works:

Ext.define("User", { extend: 'Ext.data.Model', fields: [ 'id', 'name', 'info', 'price', 'quantity', 'order_id', 'product_id' ], proxy: { type: 'ajax', //rest url : 'ex1.json', reader: { type: 'json', root: 'children' } } 

});

So, it seems that associations among models for the different levels of my nested data are not needed at all.

It works, although I am not sure whether there are drawbacks or not. I am still looking for your advise, I go by try&mistake, I do not see the underlying logic yet. Thks.


I have second thoughts. The trick to use a unique string 'children' does not seem so good. Let me consider a very simple json:

{ "users": [ { "id": 12, "name": "Ed2", "orders": [] }, { "id": 123, "name": "Ed", "orders": [ { "id": 50, "info" : "hello", "name" : "MM", "leaf" : 'true', "some_else": [] }] } ] 

}

The extJS tree I wish to get is:

Root |--ED |--ED2 |--MM 

The model is just

Ext.define("User", { extend: 'Ext.data.Model', fields: [ 'id', 'name' ], hasMany: {model: 'Order', name: 'orders'}, proxy: { type: 'ajax', //rest url : 'my_file.json', reader: { type: 'json', root: 'users' } } }); Ext.define("Order", { extend: 'Ext.data.Model', fields: [ 'id', 'name', 'info' ], belongsTo: 'User' }); 

The final output I get is just:

Root |--ED |--ED2 

is it a mistake of mine, or a missing feature? is there a way out without to change my json?

Thanks a lot

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.