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

前端 未结 5 1262
慢半拍i
慢半拍i 2021-02-04 19:18

I\'m making a TreePanel that looks like this:

\"enter

At the moment I have it \"mo

相关标签:
5条回答
  • 2021-02-04 19:29

    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.

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

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

    0 讨论(0)
  • 2021-02-04 19:37

    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,
    });
    
    0 讨论(0)
  • 2021-02-04 19:42

    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!?!

    0 讨论(0)
  • 2021-02-04 19:43

    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);
        }
    })
    
    0 讨论(0)
  • 2021-02-04 19:45

    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;}
    
    0 讨论(0)
提交回复
热议问题