sridhars711 / dynatree

Automatically exported from code.google.com/p/dynatree
0 stars 0 forks source link

Persist lazy trees #83

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Persisting a lazy tree is a little bit tricky.
Only the keys of active/focused/selected/expanded nodes are stored in cookies.
When the page is reloaded, and these cookies are present, the
activate/focus/... events are re-applied to the tree.

Because lazy nodes are not present in the reloaded tree, they cannot be
found by key, so this must currently fail.

Original issue reported on code.google.com by moo...@wwwendt.de on 14 Mar 2009 at 8:26

GoogleCodeExporter commented 9 years ago
First thoughts:

- we must evaluate the 'expanded + lazy' nodes and re-load them from the server
- we can assume, that the active and focused node are visible, after we 
restored the
expansion state
- we can NOT assume, that all selected nodes are re-loaded (may be located in
collpased nodes, and got lost, after the inital tree state was restored)

1. Possible approach: 
load expanded lazy after refresh
We could load every lazy node that has a 'expanded' cookie set.
this has to be done recursively, because lazy nodes may have lazy children.
Also, this has to be done synchrounously (we have to wait for the parents to be
loaded, before we can load the children)
--> 
  - could be slow, bad user experience

2. Possible approach: 
Store some extra data in the cookies, that would allow to display at least the 
title
of all expanded parents.
The siblings of the expanded parents could be ignored (like in Windows Vista 
explorer
et. al.).
-->
  - in worst case we would still have to store nearly the whole (large) tree in cookies.
  - The title and key may not be enough to store, since we dont know what data is
used by the custom events
  - Also, we would need special logic to reload the parent siblings

Original comment by moo...@wwwendt.de on 14 Mar 2009 at 3:15

GoogleCodeExporter commented 9 years ago

Original comment by moo...@wwwendt.de on 14 Apr 2009 at 2:24

GoogleCodeExporter commented 9 years ago
This tree widget is really quite nice, but control through javascript gets very 
hairy
when one tries to restore the state of a tree which is completely lazy loaded.

I have a tree with geographical regions in which end-users can walk through 
these
levels: world (level 0), continental regions (level 1: first lazy load), 
countries
(2), states/provinces (3), counties/municipalities (4), cities (5).

For instance, a municipality and/or a city has been selected and saved into the
database. Now, on an edit, I'll have to reconstruct the tree with that same
municipality and/or city selected. This appears to be quite difficult...

About the only way to do this currently is to use the toDict method and store 
the
structure somewhere on server.

Note that the storage space in cookies is limited to 4Kb per cookie (but of 
course IE
has bugs and limits cookie storage space to 4Kb per domain, if I'm not 
mistaken).

Anyway, point of this whole post: I'd LOVE to see some smartness to reconstruct 
a
tree with lazy nodes. Of course this slightly depends on the server 
implementation,
but I'm sure this can be solved...

I can imagine it requires to save at least all parent node keys up to level 0, 
since
otherwise it is simply impossible to know in which subtree a node is located. 
So if
the tree widget would have a method to expand all lazy parents up to a certain 
node
in a recursive and automatic way, then things would get a bit easier to control.

Hope this gave some ideas...

regards,
Bas van Gaalen

Original comment by webtweakers on 15 Apr 2009 at 1:25

GoogleCodeExporter commented 9 years ago
My current idea is to have a function like tree.getPersistInfo() which returns a
expanded key list , selectList, acive key, ...

This could then passed to tree.options.initAjax(). 
I would leave it up to the webservice to return a properly expanded tree.
Would this be a solution for you?

If we wanted to transfer/show only the minimum required parent nodes - but not 
the
siblings of expanded parents - we would have to introduce a new node status
'partlyLoaded'.
However, this should be a point of its own.

I am also a bit unhappy with the current implementation of persistance of 
non-lazy
nodes, which refires the select/activate/focus events. I will propably change
something there too.

Original comment by moo...@wwwendt.de on 15 Apr 2009 at 7:58

GoogleCodeExporter commented 9 years ago
Yes, that would work. I tried doing something like that myself, by requesting 
the
node-hierarchy from level 0 up to a saved selected node and then trying to 
expand all
levels. This was still difficult due to the asynchronous nature of Ajax. Making 
this
synchronous is not an option, though.

The hierarchy of the tree is of course known on the server - in all cases, not 
only
my geography example up there. So in fact, there should be no real reason to
implement a client-side getPersistInfo() method.

Ideally this problem should be solved without storing any extra meta data for 
the
state of the tree (requiring some kind of storage on the server, which has 
nothing to
do with the rest of the application). This means that, somehow, a list of keys 
and
the level they exist on, should be enough to expand these nodes. I imagine this
struct will look something like this in JSON:

[{level:0,key:1,children:[{level:1,key:21},{level:1,key:22}]},{level:0,key:2,chi
ldren:[...]}]

I suppose the 'level' is not even required, assuming these objects always start 
on
level 0. Maybe 'title' should be added, so that indeed this tree can be 
partially
initialized with all saved nodes selected, and nothing else loaded.

Seems doable?

Creating this object on the server is a bit of a challenge, since it has to be
constructed from the top level down. But that's what keeps (web-application)
development interesting. :)

Original comment by webtweakers on 16 Apr 2009 at 8:51

GoogleCodeExporter commented 9 years ago
getPersistInfo() could simply be a convenience function to get the cookie 
values in
an object format, like this:
{activeKey: 'id7',
 focusedKey: 'id7',
 expandedKeyList: ['id1', 'id7', 'id10'],
 selectedKeyList: ['id5, 'id6']
}

The web service that responds to initAjax() may use this information to add 
child
nodes if the parent's key is in the expandedKeyList.
Since appendAjax() is typically also already implemented, this could be done by
recursively calling some existing code (with some modifcations :-).

The other members (activeKey, focusedKey, selectedKeyList) should be evaluated 
to set
the node object attributes accordingly (activate: true, focus: true, select: 
true).

No need for any extra server-side session storage.

Only issue at the moment is, the current implementation of non-lazy persistence.
I have to make sure, that it will not interfere. (issue 84)

Original comment by moo...@wwwendt.de on 18 Apr 2009 at 7:25

GoogleCodeExporter commented 9 years ago

Original comment by moo...@wwwendt.de on 19 Apr 2009 at 5:36

GoogleCodeExporter commented 9 years ago

Original comment by moo...@wwwendt.de on 19 Apr 2009 at 5:52

GoogleCodeExporter commented 9 years ago
Fixed with release 0.5.
See http://code.google.com/p/dynatree/wiki/UpdateToVersion05
(Still alpha and open for comments!)

Original comment by moo...@wwwendt.de on 27 Apr 2009 at 4:32

GoogleCodeExporter commented 9 years ago
Should be working now.
(Tested with a simple server, that now ships with dynatree).

Original comment by moo...@wwwendt.de on 28 May 2009 at 11:07

GoogleCodeExporter commented 9 years ago
Cool, I'll be having a look at this soon and will let you know my findings...

Original comment by webtweakers on 28 May 2009 at 12:10

GoogleCodeExporter commented 9 years ago
considered verified

Original comment by moo...@wwwendt.de on 17 Jul 2012 at 4:12