我使用GWT2.1的CellBrowser和一个定制的TreeViewModel。TreeViewModel反过来使用一个AsyncDataProvider动态地获取数据。当用户单击节点时,我的AsyncDataProvider通过RPC获取结果,CellBrowser忠实地显示结果。
我觉得自己很傻,因为我无法理解这一点,但我如何以编程方式告诉CellBrowser重新加载(并显示)数据呢?我猜想我需要以某种方式为根节点获取AsyncDataProvider的句柄,然后在其上调用updateRowData() & updateRowCount(),但我看不到查询浏览器(或其模型)根DataProvider的明显方法。
我想我可以在我的AsyncDataProvider构造函数中添加寻找空参数的代码,这样就可以识别“嘿,我是根”,并在某个地方存储一个引用,但这似乎有点麻烦。当然还有更好的方法。
很抱歉在这里抛出了这么多代码,但我不知道如何将其归结为更简单的内容,并提供足够的上下文。
My AsyncDataProvider:
private static class CategoryDataProvider extends AsyncDataProvider<Category>
{
private Category selectedCategory;
private CategoryDataProvider(Category selectedCategory)
{
this.selectedCategory = selectedCategory;
}
@Override
protected void onRangeChanged(HasData<Category> display)
{
new AsyncCall<List<Category>>()
{
@Override
protected void callService(AsyncCallback<List<Category>> cb)
{
// default to root
String categoryId = "-1";
if (selectedCategory != null)
{
categoryId = selectedCategory.getCategoryId();
}
// when a category is clicked, fetch its child categories
service.getCategoriesForParent(categoryId, cb);
}
@Override
public void onSuccess(List<Category> result)
{
// update the display
updateRowCount(result.size(), true);
updateRowData(0, result);
}
}.go();
}
}My模型:
private static class CategoryTreeModel implements TreeViewModel
{
private SingleSelectionModel<Category> selectionModel;
public CategoryTreeModel(SingleSelectionModel<Category> selectionModel)
{
this.selectionModel = selectionModel;
}
/**
* @return the NodeInfo that provides the children of the specified category
*/
public <T> NodeInfo<?> getNodeInfo(T value)
{
CategoryDataProvider dataProvider = new CategoryDataProvider((Category) value);
// Return a node info that pairs the data with a cell.
return new TreeViewModel.DefaultNodeInfo<Category>(dataProvider, new CategoryCell(), selectionModel, null);
}
/**
* @return true if the specified category represents a leaf node
*/
public boolean isLeaf(Object value)
{
return value != null && ((Category) value).isLeafCategory();
}
}--最后,我是如何使用它们的:
CategoryTreeModel model = new CategoryTreeModel(selectionModel);
CellBrowser cellBrowser = new CellBrowser(model, null);发布于 2011-01-21 08:00:14
看起来很多人都有这种同一问题。下面是如何处理从AsyncDataProvider中刷新数据的方法。
首先,创建一个接口,通过包装AsyncDataProvider的受保护的onRangeChanged方法来增加刷新数据提供程序的能力。例如..。
HasRefresh.java
public interface HasRefresh<HasData<T>>{
/**
* Called when a display wants to refresh
*
* @param display the display to refresh
*/
void refresh(HasData<T> display);
}然后需要刷新的CellTable可以通过一个活动调用它,或者设置控制器逻辑。
/**
* A custom {@link AsyncDataProvider}.
*/
public class MyAsyncDataProvider extends
AsyncDataProvider<Entity> implements HasRefresh<Entity> {
public void refresh(Entity display){
onRangeChanged(display);
}
/**
* {@link #onRangeChanged(HasData)} is called when the table requests a
* new range of data. You can push data back to the displays using
* {@link #updateRowData(int, List)}.
*/
@Override
protected void onRangeChanged(
HasData<Entity> display) {
currentRange = display.getVisibleRange();
final int start = currentRange.getStart();
dataServiceQuery = context.getEntities();
dataServiceQuery
.execute(new DataServiceQueryHandler<Entity>() {
@Override
public void onQueryResponse(
DataServiceQueryResponse<Entity> response) {
updateRowCount(response.getCount(), true);
updateRowData(start, response.getEntities());
}
});
}// end onRangeChanged()
}// end MyAsyncDataProvider class发布于 2012-06-28 17:08:14
现在发现,下面的代码基本相同,只是来自HasData接口,而不是使用AsyncDataProvider。
HasData<T> display;
...
display.setVisibleRangeAndClearData(display.getVisibleRange(), true);发布于 2013-05-08 10:55:02
我不明白为什么和蔼可亲的家伙的回答被标记为“正确”,而且如此之多!?
咖啡因昏迷询问更新细胞浏览器而不是细胞表,这是完全不同的事情!
对我来说,下面的技巧奏效了:我将DataProvider定义在TreeViewModel之外,并将它们作为参数传递给构造函数。在我的例子中,它们在一开始就提供了空的数据结构。
现在,您可以从“外部”引用DataProviders,以更新Cell。
示例:
private class MyTreeViewModel implements TreeViewModel {
AbstractDataProvider<MyDataStructure> myDataProvider;
public MyTreeViewModel(AbstractDataProvider<MyDataStructure> myDataProvider)
{
this.myDataProvider = myDataProvider;
}
@Override
public <T> NodeInfo<?> getNodeInfo(T value) {
if(value == null)
{
// Level 0
return new DefaultNodeInfo<MyDataStructure>(myDataProvider, new MyCellImpl());
}
}
}
AbstractDataProvider<MyDataStructure> myDataProvider = new ListDataProvider<MyDataStructure>(new ArrayList<MyDataStructure>()); // or AsyncDataProvider
MyTreeViewModel myModel = new MyTreeViewModel(myDataProvider);
CellBrowser<MyDataStructure> cellBrowser = new CellBrowser.Builder<MyDataStructure>(myModel, null).build();
/*
here you can do some stuff, for example, bind the CellBrowser to a template with UiBinder
*/
/*
if you use a ListDataProvider, do
*/
myDataProvider.setList(myDataStructureFromSomewhere);
myDataProvider.refresh();
/*
if you use an AsyncDataProvider, do
*/
myDataProvider.updateRowData(..., myDataStructureFromSomewhere);
myDataProvider.updateRowCount(...);https://stackoverflow.com/questions/4702102
复制相似问题