Data update bug in TreeGrid

Data update bug in TreeGrid

Now there's is a bug in the TreeGrid when the Parent 'Map' is open while there's a data update for this Parent 'Map'. For example in this situation 'Map A' when I make a copy of 'Doc A'. After the update of the data nothing seems to happen, but when 'Map A' is closed and opened again;

The new data outside the parent is random; sometimes only one file from the parent and sometimes multiple files from the parent. This behavior only occurs when the parent 'Map' is open while updating the data from this 'Map'. As a workaround my program closes every 'Map' before updating it's data. But this is a lot of work and is strange behavior to the user...

This is after the copy/past action while closing 'Map A' while pasting, so the data update takes places on a closed parent. As you see, this works well and the new key is unique. Now I copy 'Copy of Doc A' again and leave 'Map A' open while pasting.

Nothing happens on the screen (with de debugger i can see the nodes are updated as they should) ... But after closing 'Map A';

As you can see, the copy action succeeded with three unique keys (the first three documents). But the two old documents (the last two) appear as ghost documents outside 'Map A'

Summarised; The TreeGrid does not update live data in the parent branch while a parent branch is open. When this parent branch is closed after this data update, the current members of this branch are viewed outside (next to) the parent branch (this is the bug). Inside the parent branch everything is ok. The ghost files are indeed with duplicated keys, but these do not originate from the server.

I'm not sure whether the duplicate nodes are really "outside" the parent map. They have the same indentation as the nodes which are supposedly "inside" the parent map. If they are really outside I would expect the duplicate node to have the same indentation as the parent map. So, I would see the following situation:

Code:

- Map A
Doc A
Copy of Doc A
Doc A (this is the duplicate node...)

The duplicate node is directly underneath the parent map. This is also how the context menu example shows the items in the GXT explorer demo. In the screenshots, however, I see that the duplicate node has the same indentation as the map's child nodes, which looks as follows:

Code:

- Map A
Doc A
Copy of Doc A
Doc A (this is the duplicate node...)

What's strange about all this is that when the parent map is closed/collapsed, the duplicate node is still visible, as follows:

Code:

+ Map A
Doc A (this is the duplicate node...)

So, the duplicate node seems to be a child of the parent map (as intended), has same indented position as the other nodes, but for some strange reason is not hidden when the parent is collapsed. Of course, this duplicate node should not be there at all, regardless of its position, but this is just an observation that might trigger some ideas.

onDataChange does not trigger render/refresh methods

onDataChange does not trigger render/refresh methods

I've found the cause of the problem

Nothing happens after the data update because the GridView is not updated (onUpdate, doRender, renderUI, renderRows, refreshRow etc.) after a data update from the server... The onDataChange(M parent) from TreeGrid does not trigger any of these methods...

Following on this, the methods from GridView are also not called when the parent branche (for example Map A) is closed after the data update. This causes the 'ghost Doc A' outside Map A after the data update and parent collapse;

Nothing happens after the data update because the GridView is not updated (onUpdate, doRender, renderUI, renderRows, refreshRow etc.) after a data update from the server... The onDataChange(M parent) from TreeGrid does not trigger any of these methods...

Maybe I'm missing something (and still without an example or how to modify our own examples I'm going to be missing things until I get lucky reproducing this), but TreeGrid.onDataChange may not call those things, but it does appear to update the ListStore that represents the actual set of items to be rendered - this happens via the TreeGrid.renderChildren method. TreeGridView, which via GridView listens to that underlying ListStore should be listening to those events, should then respond through its own remove/add events. Any StoreDataUpdateEvent coming from the TreeStore should therefore be causing a bunch of add/remove events on the ListStore, which the GridView/TreeGridView should be reading, and redrawing accordingly.

Originally Posted by rcbeuker

Following on this, the methods from GridView are also not called when the parent branche (for example Map A) is closed after the data update. This causes the 'ghost Doc A' outside Map A after the data update and parent collapse;

There must be an additional function which renders the GridView straight after the data update onDataChange(M parent)

How is the rest of this wired up? How are changes coming from the client, to the server, and back to the client? This behavior (name changes, etc) doesn't seem to be any of the standard loaders, so I'm assuming something else is in place. Then how are you wiring the load event to the TreeStore? Two provided classes that can do this for you are SubTreeStoreBinding and ChildTreeStoreBinding, based on how much of the subtree you are rewiring.

The initial post mentioned "a bug in the TreeGrid when the Parent 'Map' is open while there's a data update for this Parent 'Map'", but now it appears to be the data changed events which cause this issue - is it both, or just the one?

To be clear, I certainly believe there is a bug here, and I could believe that the bug is within GXT itself, but without a sketch of how updates are being performed, it is very difficult to say. http://www.sencha.com/examples/#Exam...itabletreegrid allows a user to cause the StoreUpdateEvents (actually, StoreRecordChangedEvent, but set autoCommit to true on the TreeStore, and you get StoreUpdateEvents), which don't seem to have the issue described. Initial experimentation with firing a real StoreDataChangedEvent doesn't seem to cause an issue either:

Your test description and images certainly don't sound like expected behavior, but we have the bug template for a reason - until we've got a test case that lets us reproduce the issue, we can't be sure we've fixed it, even following the best descriptions.

The complete story

The complete story

Hello Colin,

Thanks for your extensive attention, and my apologies for the missing bug template in this story; where're facing a strict deadline in December and this bug involves a lot of code.

How is the rest of this wired up? How are changes coming from the client, to the server, and back to the client? This behavior (name changes, etc) doesn't seem to be any of the standard loaders, so I'm assuming something else is in place.

We are using the TreeGrid as a kind of a file system for files from a remote server. Therefore we extended a RpcProxy and a TreeLoader and connected this to the TreeGrid with a ChildTreeStoreBinding. The LoadConfig from the RpcProxy is always a parent directory (starting from the root directory map) and the file server always returns a childlist from the given LoadConfig/Parent. This is actually working quit well when opening and viewing existing files (caching is enabled so the child files are only loaded at the first opening of the Parent).

Then how are you wiring the load event to the TreeStore? Two provided classes that can do this for you are SubTreeStoreBinding and ChildTreeStoreBinding, based on how much of the subtree you are rewiring.

We choose for the ChildTreeStoreBinding is this the best choise for our use-case (or should we switch to the SubTreeStoreBinding)?

From this point it's only standard Sencha code. Now a failing use-case; COPY/PASTE

I open Map A, select Doc A and choose COPY. This only saves the File_ID from Doc A. Then i select Map A and choose PASTE. This results in a copy command to the server which creates a Copy of Doc A (in Map A) and returns Map A as an updated Parent directory to our RpcProxy/TreeLoader. Our TreeLoader calls the standard load(pChangedParentItem); which results in a new list of children for Map A to the TreeGrid;

renderChildren only updates the nodes, not the store ...

renderChildren only updates the nodes, not the store ...

... but it does appear to update the ListStore that represents the actual set of items to be rendered - this happens via the TreeGrid.renderChildren method. TreeGridView, which via GridView listens to that underlying ListStore should be listening to those events, should then respond through its own remove/add events. Any StoreDataUpdateEvent coming from the TreeStore should therefore be causing a bunch of add/remove events on the ListStore, which the GridView/TreeGridView should be reading, and redrawing accordingly.