gwtproject / gwt

GWT Open Source Project
http://www.gwtproject.org
1.5k stars 371 forks source link

AsyncDataProvider should have refresh() method (just like ListDataProvider) to refresh the data of a view #5532

Closed dankurka closed 9 years ago

dankurka commented 9 years ago

Originally reported on Google Code with ID 5533

The class AsyncDataProvider is missing a refresh() (or reload()) method.
It's brother, ListDataProvider does have the refresh() method. It's probably also a
good abstract method for in AbstractDataProvider.

From dev list "Reload CellTable data":

I 'd like to add a button to reload the CellTable when it's pushed, but I can only
find:
 - cellTable.redraw(); // Doesn't reload the data from the backend
 - simplePager.firstPage(); // I don't want it to change the page

Is there an easy way to do something like cellTable.reload() or cellTable.refresh()
?

Answer 1:
... But I think the expected use is to do it in your "model" rather than
the "view" (CellTable), where the "model" (or presenter, or whatever)
will fetch the data from the backend (maybe using getVisibleRange() to
filter it) and call setRowData() on the CellTable to update it.

Answer 2:
... but really your backend should be pushing the new data into the CellTable.  For
example, if you use ListDataProvider you can call ListDataProvider#refresh() to push
the data back into the views.

Reported by gds.geoffrey.de.smet on 2010-11-03 08:32:47

dankurka commented 9 years ago
ListDataProvider has a local cache of the data in its underlying java.util.List, so
we can implement a refresh() method that pushes the data back down the the views. 

AsyncDataProvider doesn't have a local cache, so you have to request the data from
your backend.  Its up to user code to determine how you push data into the view.  You
can access the ranges of all displays via getRanges(), send the ranges to your backend,
then push the new data to the views via updateRowData(). You don't have to implement
a refresh() method since all of the required methods are public in AsyncDataProvider.

Reported by jlabanca@google.com on 2010-11-03 15:19:28

dankurka commented 9 years ago
> send the ranged to your backend

That forces us to duplicate that code from the onRangeChanged() method, doesn't it?

Reported by gds.geoffrey.de.smet on 2010-11-03 15:23:51

dankurka commented 9 years ago
Sorry for commenting on this closed issue, but I'm facing the same problem (and so do
others btw [1], and I don't see how the proposed solution can help. The issue is simply
that the AsyncDataProvider seems to assume that the only moment when data are to be
requested is when a UI event in the display happens (onRangeChanged()). But how do
I deal with a situation where data change in the back-end independently of the state
of the display(s), and I need to update the displays? Example would be if I delete
one of the items that the data provider reads via RPC from a server?

Thanks for helping out.

[1] http://stackoverflow.com/questions/4702102/gwt-how-to-programmatically-reload-cellbrowser

Reported by stoermer@okkam.it on 2011-05-03 11:57:00

dankurka commented 9 years ago
You can do celltable.setVisibleRangeAndClearData(cellTable.getVisibleRange(), true);
to refresh the celltable.

Reported by soonfatthoo on 2011-05-03 13:20:39

dankurka commented 9 years ago
Ok this can help me I guess, thanks for the hint. 

Nonetheless, to me it somehow defies the whole point of having a data provider that
maintains a list of all views on the same data. The elegant solution in my opinion
would be a method to signal the data provider that it needs to re-fetch its data.

Reported by stoermer@okkam.it on 2011-05-03 13:33:49

dankurka commented 9 years ago
The data provider has no way to know your database has already changed.  The whole point
of having data provider is to provide data to all your celltables. 

Reported by soonfatthoo on 2011-05-03 13:38:48

dankurka commented 9 years ago
Exactly, that's what I'm saying. I think my comment from above makes it very clear:
the data provider _has_ a way to react to a UI event which causes it the event handler
onRangeChanged() to be executed, and in the documentation it says that this is where
you would make an RPC call to fetch data from somewhere. 

The whole problem is that data do not only have to be (re-)fetched when a UI event
occurs, but maybe periodically, or due to something else that happens somewhere in
your app.

As you say correctly, the data provider has no way to know if the database has changed,
so what people are proposing is to add some way to _tell_ the data provider that it
needs to refresh.

The ListDataProvider is so much more intuitive in this respect.

Reported by stoermer@okkam.it on 2011-05-03 13:46:49

dankurka commented 9 years ago
Summarize:
CellTable cellTable = new CellTable();
Range range = cellTable.getVisibleRange();
//cellTable.setVisibleRangeAndClearData(range, true); //1st way
RangeChangeEvent.fire(cellTable, range);              //2nd way

Reported by bademux on 2011-05-16 23:03:33