ExtJS 4: TreeStore with both static and dynamically loaded data?

I am making a TreePanel that looks like this:

enter image description here

At the moment, I have a "bullying" with the following code:

treePanel.setRootNode({ text: 'Root', expanded: true, children: [ { text: 'General Settings', icon: kpc.cfg.baseUrl.img+'/icon_gears-bluegreen.gif', leaf: true }, { text: 'Users', icon: kpc.cfg.baseUrl.img+'/icon_users-16x16.gif', expanded: true, children: [ { text: 'Dummy User 1', icon: kpc.cfg.baseUrl.img+'/icon_user-suit.gif', leaf: true }, { text: 'Dummy User 2', icon: kpc.cfg.baseUrl.img+'/icon_user-suit.gif', leaf: true }, { text: 'Dummy User 3', icon: kpc.cfg.baseUrl.img+'/icon_user-suit.gif', leaf: true }, { text: 'Dummy User 4', icon: kpc.cfg.baseUrl.img+'/icon_user-suit.gif', leaf: true } ] } ] }); 

How can I load individual users dynamically (i.e. via storage)? In other words, how do I create a TreeStore that is a mixture of both static and dynamically loaded elements?

Thanks!

+6
source share
5 answers

The solution most suitable for me was as follows:

  • create two tree repositories - one with static content, the other configured to load my user models from the server.
  • "graph" dynamically loaded tree on a static tree.

I wrote a small tutorial that provides a demo here (in case someone wants a more detailed answer), but with a high level of code it looks like this:

 Ext.define('demo.UserModel', { extend: 'Ext.data.Model', fields: ['id', 'name', 'profile_image_url'] }); var userTreeStore = Ext.create('Ext.data.TreeStore', { model: 'demo.UserModel', proxy: { type: 'jsonp', url : 'https://myserver/getusers', reader: { type: 'json', root: 'users' } }, listeners: { // Each demo.UserModel instance will be automatically // decorated with methods/properties of Ext.data.NodeInterface // (ie, a "node"). Whenever a UserModel node is appended // to the tree, this TreeStore will fire an "append" event. append: function( thisNode, newChildNode, index, eOpts ) { // If the node that being appended isn't a root node, then we can // assume it one of our UserModel instances that been "dressed // up" as a node if( !newChildNode.isRoot() ) { newChildNode.set('leaf', true); newChildNode.set('text', newChildNode.get('name')); newChildNode.set('icon', newChildNode.get('profile_image_url')); } } } }); userTreeStore.setRootNode({ text: 'Users', leaf: false, expanded: false // If this were true, the store would load itself // immediately; we do NOT want that to happen }); var settingsTreeStore = Ext.create('Ext.data.TreeStore', { root: { expanded: true, children: [ { text: 'Settings', leaf: false, expanded: true, children: [ { text: 'System Settings', leaf: true }, { text: 'Appearance', leaf: true } ] } ] } }); // Graft our userTreeStore into the settingsTreeStore. Note that the call // to .expand() is what triggers the userTreeStore to load its data. settingsTreeStore.getRootNode().appendChild(userTreeStore.getRootNode()).expand(); Ext.create('Ext.tree.Panel', { title: 'Admin Control Panel', store: settingsTreeStore, }); 
+11
source

I believe the node parameter will help you. Set autoLoad: false , then use the beforerender event for the actual tree pane. Inside the event, call the storage load function and pass it a node . The docs claim that if this is excluded from the load() call, the root will be set by default. It would seem that you can leave your settings in the root directory of the node, and then, by invoking the load and passing it the child element of the node, you can only update users.

Contact: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.data.TreeStore-method-load for reference. Note that this download function is not the same as in Ext.data.Store ( Ext.data.TreeStore not inherited from Ext.data.Store ).

I have not had the opportunity to test this, but it seems promising.

+2
source

I have a very similar problem, and until I got it completely, the way I want it, it works mostly. I have autoLoad: false and this event handler is added:

 beforerender: function(comp, opts) { var node = this.getRootNode(); node.appendChild({test: 'Recent', id: 'recent', expandable: true, expanded: false}); node.appendChild({text: 'Current', id: 'current', expandable: true, expanded: false}); node.appendChild({text: 'All', id: 'all', expandable: true, expanded: false}); } 

3 immediate children of the root are static, then the proxy makes a request to fill them when it is expanded (transfer of the corresponding identifier).

I also had to suppress the root directory of the node by loading the listener in the repository :

  listeners: { beforeload: function(store, operation, opts) { if (operation.node.data.id == 'root') { return false; } } }, 

Hope this helps. There seems to be a better way!?!

+2
source

Here is my function to convert regular data to treeStore data, you can use this. Thus, you will no longer need treeStore:

Records: an array of records. Text: item name (retrieve from record) Children: name of children (default is "children")

 dynamicReportsStore.load({ scope: this, callback: function (records, operation) { if (operation.isComplete()) { var tree = this.buildTreeByRecords(records, 'name'); treePanel.getRootNode().removeAll(); treePanel.getRootNode().appendChild(tree); } } }); buildTreeByRecords: function (records, text, children) { var childs = [], results = [], tree = []; records = Ext.Array.map(records, function (record) { return { text: record.get(text) || record.get('id'), leaf: record.get('leaf'), expanded: true, parentId: record.get('parentId'), id: record.get('id') }; }, this); Ext.each(records, function (record) { if (Ext.isEmpty(childs[record.parentId])) { childs[record.parentId] = []; } childs[record.parentId].push(record); }, this); Ext.each(records, function (record) { if (!Ext.isEmpty(childs[record.id])) { record[children || 'children'] = childs[record.id]; results.push(record); } }, this); Ext.each(results, function (result) { if (result.parentId === 0) { tree.push(result); } }, this); return tree;} 
+1
source

I used the reader to achieve this effect in what I feel like an elegant style. Keep in mind that this is a flat store and may look a bit different with a tree repository. The concept must be translated.

 Ext.define('Ext.data.reader.a8PolicyReader', { extend: 'Ext.data.reader.Json', read: function(response) { var staticStuff, responseArr; // Static stuff staticStuff = [{name: 'some static user', id:1}, {name: 'another user', id:2}]; // extract response responseArr = Ext.decode(response.responseText); // shove them together responseArr.concat(staticStuff); // read this.readRecords(responseArr); } }) 
0
source

Source: https://habr.com/ru/post/897720/


All Articles