Rectangle 27 0

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--and 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,
});

+1 ... this was very informative, and was able to read some of the content. Athough, it seems like something in this page becomes unresponsive and crashes Google Chrome on the link provided above. clintharris.net/2011/

extjs4 - ExtJS 4: TreeStore with both static and dynamically-loaded da...

extjs extjs4
Rectangle 27 0

I believe the node parameter will help you. Set autoLoad: false, then leverage the beforerender event of the actual tree panel. Inside the event call the store's load function, and pass it a node. The docs state that if this is ommited from the load() call, it will default to the root node. It would appear that you could leave your settings in the root node and then by calling load and passing it a child node, you'd be able to update just the users.

Ext.data.TreeStore
Ext.data.Store

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

extjs4 - ExtJS 4: TreeStore with both static and dynamically-loaded da...

extjs extjs4
Rectangle 27 0

I have a very similar problem, and while I haven't gotten it to work completely like I want it to, it mostly works. I have autoLoad: false and added this event handler:

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});
}

The 3 immediate children of the root are static, then the proxy makes a request to populate them when I expand them (passing the appropriate id).

I also had to suppress the root node from loading with a listener on the store:

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

Hope this helps. It seems like there should be a better way!?!

extjs4 - ExtJS 4: TreeStore with both static and dynamically-loaded da...

extjs extjs4
Rectangle 27 0

Here is my function to convert normal data to treeStore data, you can use that. By that way, you don't need treeStore anymore:

Records: array of record. Text: name of item (get 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;}

extjs4 - ExtJS 4: TreeStore with both static and dynamically-loaded da...

extjs extjs4
Rectangle 27 0

xtype:'combo',
   fieldLabel:'Division',
   name:'division',
   valueField: 'division',
   queryMode:'local',
   store:['A','B','C'],
   displayField:'division',
   autoSelect:true,
   forceSelection:true

I know this question is really old, but just in case anyone comes looking for an answer that works out of the box; for me this was it.

I like this solution for its simplicity. A reference to the API manual where this is described: docs.sencha.com/extjs/4.1.3/#!/api/ Look for the store config.

extjs4 - Filling Extjs Combobox with static data - Stack Overflow

extjs extjs4
Rectangle 27 0

I used a reader to achieve this effect in what I feel to be an elegant fashion. Mind you this is with a flat store and may look a little different with a tree store. The concept should translate.

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);
    }
})

extjs4 - ExtJS 4: TreeStore with both static and dynamically-loaded da...

extjs extjs4
Rectangle 27 0

xtype:'combo',
       fieldLabel:'Division',
       name:'division',
       queryMode:'local',
       store:['A','B','C'],
       displayField:'division',
       autoSelect:true,
       forceSelection:true

Another Alternative is listed right in the docs of the ComboBox:

// The data store containing the list of states
    var states = Ext.create('Ext.data.Store', {
        fields: ['abbr', 'name'],
        data : [
            {"abbr":"AL", "name":"Alabama"},
            {"abbr":"AK", "name":"Alaska"},
            {"abbr":"AZ", "name":"Arizona"}
            //...
        ]
    });

    // Create the combo box, attached to the states data store
    Ext.create('Ext.form.ComboBox', {
        fieldLabel: 'Choose State',
        store: states,
        queryMode: 'local',
        displayField: 'name',
        valueField: 'abbr',
        renderTo: Ext.getBody()
    });

extjs4 - Filling Extjs Combobox with static data - Stack Overflow

extjs extjs4