Я использую GWT 2.1 CellBrowser с пользовательским TreeViewModel
. TreeViewModel, в свою очередь, использует AsyncDataProvider
для динамического извлечения данных. Все это прекрасно работает - когда пользователь нажимает на узел, мой AsyncDataProvider извлекает результаты через RPC, и CellBrowser покорно отображает их.
Я чувствую себя глупо из-за того, что не могу понять это, но как я могу программно сказать CellBrowser перезагрузить (и отобразить) данные? Я предполагаю, что мне нужно каким-то образом получить дескриптор AsyncDataProvider для моего корневого узла, а затем вызвать updateRowData () & updateRowCount () для него, но я не вижу очевидного способа запроса браузера (или его модели) для корневого DataProvider.
Полагаю, я мог бы добавить код в свой конструктор AsyncDataProvider, который ищет нулевой аргумент, и таким образом распознавать «эй, я корень» и хранить ссылку где-нибудь, но это кажется хакерским. Конечно, есть лучший способ сделать это.
Извините за то, что выгрузил здесь столько кода, но я не знаю, как свести это к чему-то более простому и все же предоставить достаточно контекста.
Мой 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();
}
}
Моя модель:
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);