Some issues with treeview lazy loading (on-demand)

4 posts, 0 answers
  1. Bridge24
    Bridge24 avatar
    90 posts
    Member since:
    Jan 2009

    Posted 02 Nov 2017 Link to this post

    Hi Telerik, we use the kendo treeview and we need to load-on-demand subitems.

    We have some issues.

    1. When the treeview have lots of subitems, it generates too many "databind" when we expand it, if loadOnDemand = false. 
    But, that way, we are able to load our subitems correctly.

     

    2. So, we prefer to use loadOnDemand = false, that generates only 2 databind, 1 when we expand, and 1 other when we set the data.

    But, we're unable to set the data, if we don't add a "setTimeout", because the data item is incomplete! It looks like the "expand" event is raising too quickly, .items list doesn't contains our "loading..." item, and if I set new data to it, nothing happen.

    If I add a setTimeout,the argument is ok and I can load my subitems.

    So, my suggetsions are: 

    1. do not generate too many databind event if loadOnDemand = false?

    2. can you raise the "expand" event when the data is really ready to be used?

    Or, is there something we're doing wrong?  We can continue using the settimeout, in fact,it works in our case because we do an "ajax" call.  But, if my data is in "cache" and I don't need ajax call, I must do a setTimeout.

    Sample: 

    https://dojo.telerik.com/isuGOn/134

    Thank you

  2. Ivan Danchev
    Admin
    Ivan Danchev avatar
    2062 posts

    Posted 06 Nov 2017 Link to this post

    Hello,

    The described behavior with regard to the difference in when the dataBound event fires with loadOnDemand enabled/disabled is expected. Let me elaborate more. The dataBound event fires when there is a change in the parent node's child nodes. For example such a change is loading the child nodes of a parent node. In your scenario it fires more times (when you expand a node) with loadOnDemand disabled, because the manually added (fillSubItems function) child nodes are specified as parent nodes (the items property):
    var fillSubItems = function(dataItem){
      var txt = dataItem.text;
      var items = [];
      for (var i = 0 ; i < 10 ; i++){
        items.push({text: txt + "_sub_" + i, items: [emptyItem]})
      }
      return items
    }

    Thus the event fires for every added child node because of its own child nodes. With loadOnDemand enabled a node does not contain children until it is expanded. Once it is expanded its child nodes are loaded. That is why in the same situation: on Level1 expand the event does not fire for every Level2 node because there is no change to the Level2 nodes own child nodes. The event will fire for a Level2 node when it is expanded and its Level3 nodes are loaded.
    As for the expand event, it always fires before the dataBound event. This is how it is by design and this behavior is not configurable. See this dojo example, which shows how it works with loadOnDemand enabled. The chain of events is the following: initial dataBound event fires, on expand of the parent the expand event fires followed by the dataBound event (because the expanded node's children are loaded). The same happens if you then expand the Level2 node (Steven Buchanan): first the expand event fires then the dataBound event.

    Regards,
    Ivan Danchev
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  3. Bridge24
    Bridge24 avatar
    90 posts
    Member since:
    Jan 2009

    Posted 28 Nov 2017 in reply to Ivan Danchev Link to this post

    We finally found a solution for our ".children not available" issue in the expand.

    We no longer need the setTimeout, but we need to "initialize" the sub-datasource, like that:

    expand: function(e){          

      var item = tv.dataItem(e.node);
      item.load(); // <--- TO MAKE .children.data usable
      item.children.data(our-new-data-array-to-load)

    }

    Now, we're able to add data to children without waiting for setTimeout.

    Also, we sometimes want to add subitems to "closed" nodes, before the expand.  We use the same method, calling the ".load" on the subitem, before using the .children.data(xxx) method, and it work fine!

    And, for the "items: [emptyItem]", it's a "hack" we must use because if we put an empty list, even if we set hasChildren = true, the arrow is not visible.  So we use the "fakeItem" method, to display the expand arrow, and after, we remove that fakeItem and replace it with our real data.

    And, that's a nice workaround, because if we need to do an ajax call, we see the fakeItem didplaying "loading..." before it's replaced by the real data!

  4. Ivan Danchev
    Admin
    Ivan Danchev avatar
    2062 posts

    Posted 30 Nov 2017 Link to this post

    Hello Daniel,

    Thank you for the follow up and the explanation. I am glad you have found an approach that works in your scenario.

    Regards,
    Ivan Danchev
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top