1. #1
    Sencha User
    Join Date
    Jun 2011
    Location
    Iasi, Romania
    Posts
    144
    Answers
    5
    Vote Rating
    0
    catalin.ciobanu is on a distinguished road

      0  

    Default Answered: Tricky tree/treegrid

    Answered: Tricky tree/treegrid


    Hello, is possible to build a tree/treegrid by the following scenario?
    Scenario:
    Get some json data from server like this:
    Code:
    {
       object1{
                      name
                      title
                      id
                      children{
                                  object2
                                            {name1
                                              length1
                                              some_other_property1
                                             }
                                  object2
                                           { name2
                                              length2
                                              some_other_property2
                                             }
                    }
    }
    When the tree first loads, I want to load only object1 items. When I expand an object1 I want the loader to load the object2 items in a remote way.
    I am able to get at one call only objects with type object1and on a different call, the corresponding items with type object2 but I don't know how to set a ModelType for my JsonReader because object1 and object2 have different properties, different fields.

    I don't have access to modify the way that data comes from server. So I will need to find a way to do this. Getting all data in a call I tried, using local data but I want to do this in a remote way.

  2. It looks like you might want two proxies, and a single reader for each proxy. I'll assuming you have these already figured out, and will refer to them as nodeProxy and leafProxy, where the nodeProxy asks for non-leaf nodes, and leafProxy only gets the leaf nodes. Additionally, I'm going to refer to nodeJsonReader and leafJsonReader, JsonReader objects set up with the correct ModelTypes.

    TreeLoader is an interface with two methods, one to get children, one to check if children exist. You started off by extending BaseTreeLoader, but this class is designed to take at most one proxy/reader. So we're going to need to cheat slightly. Our interest lies in changing how it gets data from the server, and how it reads it. Construct the BaseTreeLoader with a null for the proxy (or reader), and we'll implement our own way of pulling in data, selecting the correct proxy/reader combination.

    Code:
    new BaseTreeLoader<ModelData>((DataProxy<?>)null) {
      protected void loadData(Object config, AsyncCallback<List<M>> callback) {
        if (isNodeObject(config)) { //so incoming data are leaves
          leafProxy.load(leafJsonReader, config, callback);
      } else { //incoming data are nodes
          nodeProxy.load(nodeJsonReader, config, callback);
      }
    }
    If I'm mistaken, and you only make one kind of request, just with different parameters, here is a different approach: DataReader is just an interface with one method. Readers from the previous example are used to make one big reader here (not tested either):

    Code:
    DataReader<ModelData> everythingReader = new DataReader<ModelData>() {
      public ModelData read(Object loadConfig, Object data) {
        if (isNodeObject(loadConfig)) {//so incoming is a leaf 
          return leafJsonReader.read(loadConfig,data);
        } else {// so incoming is a node
          return nodeJsonReader.read(loadConfig,data);
        }
      }
    }

  3. #2
    Sencha User
    Join Date
    Jun 2011
    Location
    Iasi, Romania
    Posts
    144
    Answers
    5
    Vote Rating
    0
    catalin.ciobanu is on a distinguished road

      0  

    Default


    -what method should I override if I want to execute a different request for data after the first load ?
    -on expanding a folder I want to make a request for getting a different type of data!

  4. #3
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,634
    Answers
    107
    Vote Rating
    79
    Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice

      0  

    Default


    If the TreePanel is generic on ModelData, and the treestore and treeloader as well, anything that extends ModelData can be loaded into the store and thus displayed on the tree. The TreeLoader will get an item passed to loadChildren, and you can check the type of it to decide how to proceed, and what server call to make to load items.

    This is a pretty common use case, and shouldn't be too hard to accomplish. If you are having issues making this work, please share the basic models you want to work with in the tree, and the loader code you've come up with so far.

  5. #4
    Sencha User
    Join Date
    Jun 2011
    Location
    Iasi, Romania
    Posts
    144
    Answers
    5
    Vote Rating
    0
    catalin.ciobanu is on a distinguished road

      0  

    Default


    well, the Tree is ModelData... as the store and loader:
    My problem is that I don't know how to setup the ModelType .. because I will load 2 different types of data with different properties. The first time I want my model type to load the folders.
    Code:
            ModelType type = new ModelType();
            type.setRecordName(null);
            type.setRoot("folder_model");
            type.addField("description", "description");
            type.addField("name", "name");
            type.addField("properties", "properties");
            type.addField("title", "title");
            type.addField("uuid", "uuid");
    For this JSON data:
    Code:
    {
        "folder_model":[
                            {
                                "description":"description1",
                                "name":"test1",
                                "properties":{},
                                "title":"title1",
                                "uuid":"0610847b-6b7f-4b91-9e6d-0def9b7944d0"
                            },
                            {
                                "description":"description2",
                                "name":"test2",
                                "properties":{},
                                "title":"title2",
                                "uuid":"bd9cd53d-b3c0-4c7c-b623-a1a11805724d"
                            },
                            {
                                "description":"description3",
                                "name":"test3",
                                "properties":{number},
                                "title":"title3",
                                "uuid":"ca235a81-ca6a-40b6-8490-027fec5df02a"
                            }
                        ]
    }
    After the first load, I want to get the files (the children) of a folder so I make another request and I will need this model type:
    Code:
           ModelType type = new ModelType();
            type.setRecordName(null);
            type.setRoot("document_model");
            type.addField("name", "name");
            type.addField("note", "note");
            type.addField("object", "object");
            type.addField("properties", "properties");
            type.addField("uuid", "uuid");
    For this data:
    Code:
    {"document_model":[{
                            "name":"ssss",
                            "note":"no_note",
                            "object":"Object_dwfa",
                            "properties":{
                                            "number":"Number_sssda"
                                        },
                            "uuid":"1fd1cf79-8709-48be-b759-b53829c1b86c"
                        },
                        {
                            "name":"ssss",
                            "note":"some note",
                            "object":"Ca1Obj",
                            "properties":{
                                            "number":"CinNumber"
                                        },
                            "uuid":"757c0a49-95e5-4656-99f8-99c17976132a"
                        },
                        {
                            "name":"Cat23",
                            "note":"som211",
                            "object":"CObjOsk",
                            "properties":{
                                            "number":"NumeroAlto"
                                        },
                            "uuid":"aec5895e-3f65-4b4a-9f99-5216d0a7c082"
                        }]
    }
    So when I expand the tree I should make a request sending the name of the event (EventGetDocuments) along the id of the folder (I suppose model.get("uuid")). How could I set the ModelType in a dynamic way .. to change it on expand ?

    I have to say: The first load it is ok, works as expected. The problem shows up when I expand one of the folders of my tree as the loader makes the same request (sending the expanded model, with the first event ... EventGetFolders)
    Last edited by catalin.ciobanu; 3 Oct 2011 at 7:45 AM. Reason: I have to say ...

  6. #5
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,634
    Answers
    107
    Vote Rating
    79
    Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice

      0  

    Default


    Ok, I think I am following now - you've got a slightly more interesting problem than I had understood before.

    You didn't post a lot of code, so I am assuming you've got some wiring that creates a JsonReader with that ModelType, and probably an HttpProxy that loads this content. Both are presumably given to a TreeLoader. My suggestions that follow are based on this assumption - if they are incorrect, please let me know.

    With two ModelTypes, it seems to make sense to make two JsonReaders. The purpose of a DataReader is to turn some data formatted for transport into models which can be used by your application. We'll need one for each of the formats you'll be accepting, and another custom DataReader implementation to wrap them and decide which one to use.

    Take a look at the main method in DataReader - it accepts a load config, the data that came over the wire, and returns the model objects you need. We'll be passing the data into which ever reader fits the current use case, and we'll figure that out from the loadConfig - but the specific logic there is up to you. I believe the loadConfig will be the parent model, which hopefully is enough.

    Once you can decide which reader to use, invoke read on the relevant reader, and return the result so the loader can pass it to the store, and on to the

  7. #6
    Sencha User
    Join Date
    Jun 2011
    Location
    Iasi, Romania
    Posts
    144
    Answers
    5
    Vote Rating
    0
    catalin.ciobanu is on a distinguished road

      0  

    Default


    Colin thanks a lot for taking from your time to help me!
    You are right with your assumption.

    Basically, I will have to develop a custom reader .. extending DataReader, giving a new (suitable for my needs) logic to method --public D read(Object loadConfig, Object data)--
    Once you can decide which reader to use, invoke read on the relevant reader, and return the result so the loader can pass it to the store
    I don't realy know where to do this; I would say in loadChildren .. is that right ?
    And also how should I specify a different event ?

    The first load I make with this data:
    Code:
            HashMap<String, String> hm = new HashMap<String, String>();
            hm.put("eventname", "EventGetFolders");
            hm.put("requesttype", "ajax");
            String postData = Utilities.convertToPost(hm);
            RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,
                    URL.encode(GWT.getHostPageBaseURL() + "RequestServlet"));
            builder.setHeader("Content-type", "application/x-www-form-urlencoded");
    ...........
    And after, at expanding a folder, I want to specify this data:
    Code:
            HashMap<String, String> hm = new HashMap<String, String>();
            hm.put("eventname", "EventGetDocuments");
            hm.put("uuidFolder", "the expanded folder's id");
            hm.put("requesttype", "ajax");
            String postData = Utilities.convertToPost(hm);
            RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,
                    URL.encode(GWT.getHostPageBaseURL() + "RequestServlet"));
            builder.setHeader("Content-type", "application/x-www-form-urlencoded");
    .........................
    And how i use it...
    Code:
    HttpProxy<ListLoadResult<ModelData>> proxy = new HttpProxy<ListLoadResult<ModelData>>(
                    builder);
    
            ModelType type = new ModelType();
            ........
    
            reader = new MyJsonReader<List<ModelData>>(type);
            
            loader = new BaseTreeLoader<ModelData>(proxy, reader) {
                @Override
                protected Object prepareLoadConfig(Object config) {
                    return super.prepareLoadConfig(config);
                }
    
                @Override
                public boolean hasChildren(ModelData parent) {
                    return true;
                }
            };
    
            treeStore = new TreeStore<ModelData>(loader) {
                @Override
                public boolean hasChildren(ModelData parent) {
                    return true;
                }
            };
            
            MyStoreSorter sorter = new MyStoreSorter(FilesTree.dir);
            treeStore.setStoreSorter(sorter.getSorter());
    
            treeStore.setKeyProvider(new ModelKeyProvider<ModelData>() {
                public String getKey(ModelData model) {
                    return "node_" + model.<String> get("uuid");
                }
            });

  8. #7
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,634
    Answers
    107
    Vote Rating
    79
    Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice

      0  

    Default


    It looks like you might want two proxies, and a single reader for each proxy. I'll assuming you have these already figured out, and will refer to them as nodeProxy and leafProxy, where the nodeProxy asks for non-leaf nodes, and leafProxy only gets the leaf nodes. Additionally, I'm going to refer to nodeJsonReader and leafJsonReader, JsonReader objects set up with the correct ModelTypes.

    TreeLoader is an interface with two methods, one to get children, one to check if children exist. You started off by extending BaseTreeLoader, but this class is designed to take at most one proxy/reader. So we're going to need to cheat slightly. Our interest lies in changing how it gets data from the server, and how it reads it. Construct the BaseTreeLoader with a null for the proxy (or reader), and we'll implement our own way of pulling in data, selecting the correct proxy/reader combination.

    Code:
    new BaseTreeLoader<ModelData>((DataProxy<?>)null) {
      protected void loadData(Object config, AsyncCallback<List<M>> callback) {
        if (isNodeObject(config)) { //so incoming data are leaves
          leafProxy.load(leafJsonReader, config, callback);
      } else { //incoming data are nodes
          nodeProxy.load(nodeJsonReader, config, callback);
      }
    }
    If I'm mistaken, and you only make one kind of request, just with different parameters, here is a different approach: DataReader is just an interface with one method. Readers from the previous example are used to make one big reader here (not tested either):

    Code:
    DataReader<ModelData> everythingReader = new DataReader<ModelData>() {
      public ModelData read(Object loadConfig, Object data) {
        if (isNodeObject(loadConfig)) {//so incoming is a leaf 
          return leafJsonReader.read(loadConfig,data);
        } else {// so incoming is a node
          return nodeJsonReader.read(loadConfig,data);
        }
      }
    }

  9. #8
    Sencha User
    Join Date
    Jun 2011
    Location
    Iasi, Romania
    Posts
    144
    Answers
    5
    Vote Rating
    0
    catalin.ciobanu is on a distinguished road

      0  

    Default


    Thank you very much Colin, I got a little help and I made it without using proxy/loader/reader at all.
    Just getting the string, parsing the JSON and adding the element to the store.

    I send the wanted request using the BeforeExpand event with a listener which makes the request. It's faster and it works just fine .. which is good.

    Thank you again, keep up the good work.

  10. #9
    Sencha - GXT Dev Team
    Join Date
    Feb 2009
    Location
    Minnesota
    Posts
    2,634
    Answers
    107
    Vote Rating
    79
    Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice Colin Alworth is just really nice

      0  

    Default


    Glad to hear it. The Loader can easily be used alone, as you've noticed, and the readers/proxies are meant as tools to plug into it -- but if you can easily do the job with a simpler tool, that is almost always the right choice.

Thread Participants: 1

film izle

hd film izle

film sitesi

takipci kazanma sitesi

takipci kazanma sitesi

güzel olan herşey

takipci alma sitesi

komik eğlenceli videolar