Search code examples
extjsextjs4

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


I'm making a TreePanel that looks like this:

enter image description here

At the moment I have it "mocked up" 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 the individual users dynamically (i.e., via a store)? In other words, how do I make a TreeStore that is a mixture of both static and dynamically-loaded items?

Thanks!


Solution

  • The solution that worked best for me was to:

    1. create two tree stores--one with the static content, another set up to load my User models from the server.
    2. "graph" the dynamically-loaded tree onto the static tree.

    I wrote up a little tutorial that includes a runnable demo here (in case anyone wants a more detailed answer), but at a high level the code 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 
            // (i.e., 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's being appended isn't a root node, then we can 
                // assume it's one of our UserModel instances that's 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,
    });