Results 1 to 4 of 4

Thread: Tree/Node expand recursively broken

    Looks like we can't reproduce the issue or there's a problem in the test case provided.
  1. #1
    Sencha Premium Member
    Join Date
    Jul 2007
    Enschede, The Netherlands

    Default Tree/Node expand recursively broken


    I'm trying to expand a tree's rootnode recursively.
    First, I tried the TreePanel's but it gives an error:

    Then I tried to use the RootNode's.expand method:
    rootNode.expand(true, callbackFn, scope);
    but the callbackFn is called directly when the first level of nodes are loaded. My tree has more nested nodes that are not loaded.

    Looking in the code of the NodeInterface, I found the reason:

    expandChildren: function(recursive, callback, scope, /* private */ singleExpand) {
        for (i = 0; i < ln; ++i) {
            node = allNodes[i];
            if (!node.isLeaf()) {
                expandNodes[expandNodes.length] = node;
        ln = expandNodes.length;
        for (i = 0; i < ln; ++i) {
            // Should be: expand(recursive, callback, scope)
        // And directly, the callback is called, even if more childNodes need to be loaded
        if (callback) {
            Ext.callback(callback, scope || me, [me.childNodes]);
        // I tried: 
        // if(!ln && callback) {
        //    Ext.callback(callback, scope || me, [me.childNodes]);
        // }
        // But that calls the callback for every node that has its childnodes loaded.
    Looking through the code, I didn't find an easy way to fix it. Of course, loading nested trees is a more advanced asynchronously topic, but would it not be a great plus if ExtJs would provide natively some of the higher level functionality like async?

    Recursively loading the tree is something along these lines using an async.queue:
    var list = [],
        allNodesLoadedFn = function() {
            console.log("The END");
        nodeLoadedFn = function(node) {
            console.log("Loaded node "+node.get("Name"));
        taskFn = function(node, callback) {
            // Mark the node as being loaded
            node.expand(false, function(childNodes) {
                // Node is loaded/expanded now
                Ext.Array.remove(list, node);
                // This calls the taskCompletedFn where optional childnodes 
                // are added as separate tasks    
                for(var i=0;i<childNodes.length;i++) {
                    queue.push(childNodes[i], nodeLoadedFn);
                // Inform async queue we're done for this node                
                // Unfortunately the async.queue doesn't have a callback when 
                // the queue is empty. Use this list as a backup. If it's empty, we're ready.
                if(list.length==0) {
        queue = async.queue(taskFn, 3);
    queue.push(rootNode, nodeLoadedFn);
    Which might be totally unreadable for some, but it works. And you can even set the number of nodes loading/expanding at the same time by changing the '3' in the line.

    queue = async.queue(taskFn, 3);
    PS: Keep up the good work. Loving it.

  2. #2
    Sencha Premium User mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Gainesville, FL


    Thanks for the report! I have opened a bug in our bug tracker.

  3. #3


    Many thanks for this workaround - beautiful.

  4. #4
    Touch Premium Member
    Join Date
    Mar 2012


    can some one post the workaround, I'm still seeing this in 5.1.1

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts