1. #1
    Sencha User
    Join Date
    Sep 2010
    Posts
    58
    Answers
    1
    Vote Rating
    0
    pret is on a distinguished road

      0  

    Default Answered: Tree: Using a Store with an Ajax proxy, how to preload ALL childrens?

    Answered: Tree: Using a Store with an Ajax proxy, how to preload ALL childrens?


    Hi all,

    I'm trying to create a tree that preloads all its items (nodes) with a single ajax request. I'm actually returning this from the server:

    Code:
    {"success":true,"msg":"","root":{"text":"Online","leaf":false,"children":[{"leaf":true,"text":"Someone"},{"leaf":true,"text":"Someone Else"}]}
    The thing is that when it loads the elements, it only appears the node "Online" collapsed. When I try to expand it, it sends another request to fetch its children.

    Is there a way to load all nodes in the tree with a single ajax request? I'll show you my code:

    Code:
            this.store = Ext.create('Ext.data.TreeStore', {
                autoLoad:       true,
                proxy:          {
                    type:           'ajax',
                    url :             'myurl.php',
                    reader:         {
                        type:           'json',
                        root:           'root'
                    }
                }
            });
            this.tree = Ext.create('Ext.tree.Panel', {
                title:              'Friends',
                rootVisible:        false,
                lines:              false,
                autoScroll:         true,
                tools:              [{
                    type:               'refresh',
                        var root = this.tree.getRootNode();
                        root.collapseChildren(true, false);
                        this.store.load();
                    },
                    scope:              this
                }],
                store:              this.store
            });

    Thanks in advance.

  2. A few observations:
    1. Your JSON is invalid. You're missing the closing }
    2. Your tools config is invalid. Seems you've cut the line specifiying the handler function.
    3. Once I corrected those 2 syntactic errors I still couldn't get it to do what you described. I had to add in an expanded root node as well.
    4. As far as I can tell, autoLoad: true doesn't do a great deal in this example.

    Once I'd fixed all those problems I could then see the scenario you've described. I believe the problem here surrounds the use of a root on the reader. For reasons I don't entirely understand, the root config option is used by a TreeStore to determine the property that contains the child nodes. Quite why there isn't a separate option called childProperty I don't know. Maybe I'm missing another config option somewhere but as far as I could tell the following configuration is the simplest way to do it:

    Code:
    reader: {
        type: 'json',
        getResponseData: function() {
            return [Ext.data.reader.Json.prototype.getResponseData.apply(this, arguments).root];
        }
    }

  3. #2
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,590
    Answers
    541
    Vote Rating
    322
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    A few observations:
    1. Your JSON is invalid. You're missing the closing }
    2. Your tools config is invalid. Seems you've cut the line specifiying the handler function.
    3. Once I corrected those 2 syntactic errors I still couldn't get it to do what you described. I had to add in an expanded root node as well.
    4. As far as I can tell, autoLoad: true doesn't do a great deal in this example.

    Once I'd fixed all those problems I could then see the scenario you've described. I believe the problem here surrounds the use of a root on the reader. For reasons I don't entirely understand, the root config option is used by a TreeStore to determine the property that contains the child nodes. Quite why there isn't a separate option called childProperty I don't know. Maybe I'm missing another config option somewhere but as far as I could tell the following configuration is the simplest way to do it:

    Code:
    reader: {
        type: 'json',
        getResponseData: function() {
            return [Ext.data.reader.Json.prototype.getResponseData.apply(this, arguments).root];
        }
    }

  4. #3
    Sencha User
    Join Date
    Sep 2010
    Posts
    58
    Answers
    1
    Vote Rating
    0
    pret is on a distinguished road

      0  

    Default


    First of all, thanks for taking the time to read and try my case. It's nice to see people willing to help like you!

    I apologize for my code, I pasted it at work before I went out and it seems I didn't copy well all the information. The JSON response (1) and the tools (2) are ok, it was my mistake when trying to copy the example and removing all the information that were no relevant.

    About the 3) point, I've added "expanded" true to all the nodes that were not "leaf", but the problem was that for each of these nodes, it was sending a request automatically to ask for the children.

    Finally, about 4), the TreeStore doesn't use the "autoLoad" property? I wanted to load the tree at the moment of instantiation.

    I'm not at work right now, but tomorrow I'll give your example a try and I'll tell you how it goes.


    Thanks a lot for your help!

  5. #4
    Sencha Premium Member skirtle's Avatar
    Join Date
    Oct 2010
    Location
    UK
    Posts
    3,590
    Answers
    541
    Vote Rating
    322
    skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future skirtle has a brilliant future

      0  

    Default


    About the 3) point, I've added "expanded" true to all the nodes that were not "leaf", but the problem was that for each of these nodes, it was sending a request automatically to ask for the children.
    I think you've misunderstood. The point I was making is that I couldn't get your code to work without adding a root node to the store (I wasn't referring to the root in your JSON or in the reader). You can ignore what I said about it being expanded, that's the default anyway with rootVisible: false.

    All that said, once you've got all of this working it should be possible to put expanded: true on all the non-leaf nodes if that's what you want. Currently it isn't picking up the children at all so setting the nodes to expanded will just force them to load remotely as you've described.

    Finally, about 4), the TreeStore doesn't use the "autoLoad" property? I wanted to load the tree at the moment of instantiation.
    As far as I can tell that setting won't do it. Setting the root node to expanded will force it to load immediately. As I've already mentioned, this is the default with a hidden root.

  6. #5
    Sencha User
    Join Date
    Sep 2010
    Posts
    58
    Answers
    1
    Vote Rating
    0
    pret is on a distinguished road

      0  

    Default


    Sorry for the misunderstanding. Now I understand what you mean. I didn't try that way. I'll give it a try tomorrow at work and keep you posted about how it goes.


    Thanks a lot for your help!

  7. #6
    Sencha Premium Member hsurya's Avatar
    Join Date
    Feb 2008
    Posts
    12
    Vote Rating
    1
    hsurya is on a distinguished road

      0  

    Default use expandAll()

    use expandAll()


    If you mean you want to open all nodes upon ajax request --> use expandAll() function, that simple.
    See my code for tree example at http://www.sencha.com/forum/showthre...fined&p=656056

  8. #7
    Sencha User
    Join Date
    Sep 2010
    Posts
    58
    Answers
    1
    Vote Rating
    0
    pret is on a distinguished road

      0  

    Default


    Hi guys,

    Using "expandAll" after the store is loaded is having the same effect that using expand: true in all non leaf nodes. It fires a request for each of the non leaf nodes, even if all the nodes are loaded in the first request.

    This is true even using the following code:

    Code:
            this.store = Ext.create('Ext.data.TreeStore', {            
                autoLoad:       true,
                proxy:            {
                    type:               'ajax',
                    url :                 'myurl.php',
                    reader:            {
                        type:               'json',
                        root:               'data'
                    }
                }
            });
            this.tree = Ext.create('Ext.tree.Panel', {
                title:                   'Friends',
                rootVisible:        true,
                lines:                  false,
                autoScroll:         true,
                root:                 {
                    text:                  'Friends',
                    id:                     'root',
                    expanded:         true
                },
                tools:              [{
                    type:                'refresh',
                    handler:            function() {
                         this.reloadTree();
                    },
                    scope:              this
                }],
                store:              this.store
            });
    As you can see, I've changed the "root" property of the proxy's reader to "data". My response is something like:

    Code:
    {"success":true,"msg":"","data":{"text":"Group","expanded":true,"children":[{"id":1,"leaf":false,"text":"Online","expanded":true,"iconCls":"icon-friends-online","children":[{"id":2,"leaf":true,"text":"Friend 1","iconCls":"icon-status-online"},{"id":3,"leaf":true,"text":"Friend 1","iconCls":"icon-status-away"},{"id":4,"leaf":true,"text":"Friend 1","iconCls":"icon-status-busy"},{"id":5,"leaf":true,"text":"Friend 1","iconCls":"icon-status-offline"}]}]}}
    So, I've changed the code removing the configuration of the "root" property from the proxy's reader:

    Code:
                proxy:          {                
                    type:           'ajax',
                    url :             'myroute.php',
                    reader:         {
                        type:           'json'
                    }
                }
    And returning directly the nodes like this it works:

    Code:
    {"text":"Group","expanded":true,"children":[{"id":1,"leaf":false,"text":"Online","expanded":true,"iconCls":"icon-friends-online","children":[{"id":2,"leaf":true,"text":"Friend 1","iconCls":"icon-status-online"},{"id":3,"leaf":true,"text":"Friend 1","iconCls":"icon-status-away"},{"id":4,"leaf":true,"text":"Friend 1","iconCls":"icon-status-busy"},{"id":5,"leaf":true,"text":"Friend 1","iconCls":"icon-status-offline"}]}]}
    The thing is that I'd like to return additional information besides the nodes in the response. I still don't understand why it doesn't work using the root property of the reader. BUT.. using the suggestion of skirtle worked:

    Code:
                    reader:         {                    
                             type:                         'json',
                             getResponseData:     function() {
                                    return [Ext.data.reader.Json.prototype.getResponseData.apply(this, arguments).data];
                           }
                    }
    It's maybe a bug that it works like this but not with the "root" property or I'm missing something?


    Thanks a lot guys!

Thread Participants: 2