[英]How to properly implement MVP in GWT for a CellTree?
想象一下,我有一個CellTreeWidget
類,其中包含一個CellTree
。
我想寫一個演講者,與
CellTreeWidget
實例和 CellTreeWidget
顯示的數據是項目列表。 每個項目都有一個父項目,並且屬於一個容器。
public class Container
{
public List<Item> getItemList();
public void setItemList(List<Item> aItemList);
}
public class Item
{
public int getItemId();
public int getParentItemId();
}
演示者涉及以下過程:
Presenter.startEdit
)。 Presenter.save
)。 當用戶選擇一個容器時,必須更新CellTreeWidget
以顯示新選擇的容器的項目。
當用戶保存對容器所做的更改時,演示者必須
步驟2是必需的,因為用戶能夠在客戶端上創建新項目。 當它們保存在服務器上時,它們的數據(主鍵)將被更改。
為了實現這一點,有人告訴我使用以下方法:
public class Presenter
{
private RemoteService service;
private View view;
private ListDataProvider<Item> dataProvider;
private Container data;
public Presenter()
{
dataProvider = new ListDataProvider<Item>(new ItemProvidesKey());
}
public void setService(final RemoteService aService)
{
service = aService;
}
public void setView(final View aView)
{
view = aView;
final HasData<Item> dataToDisplay = view.getDisplay();
if (dataToDisplay != null)
{
dataProvider.addDataDisplay(dataToDisplay);
}
}
public void save() {
List<Item> allPages = new ArrayList<Item>();
allPages.addAll(dataProvider.getList());
data.setItemList(allPages);
service.save(data, new AsyncCallback<ContainerSaveResult>() {
@Override
public void onSuccess(ContainerSaveResult result) {
afterSave(result);
}
@Override
public void onFailure(Throwable caught) {
Window.alert("Save error: " + caught.getMessage());
}
});
}
protected void afterSave(ContainerSaveResult result)
{
for (final Page curItem : dataProvider.getList())
{
final Integer oldId = curPage.getItemId();
final Integer newId = result.getNewItemIdsByOldItemIds().get(oldId);
if (newId != null)
{
curPage.setItemId(newId);
}
}
dataProvider.flush();
}
public void startEdit(Container aContainer)
{
data = aContainer;
if (data != null)
{
view.getDisplay().setRowCount(data.getItemList().size(), true);
dataProvider.setList(data.getItemList());
}
}
}
CellTreeWidget
實現View
接口,其定義如下:
public interface View extends IsWidget, HasSelectionChangedHandlers {
HasData<Item> getDisplay();
}
這種方法的問題在於,我看不到任何明顯的方法在CellTreeWidget
類中提供方法HasData<Item> getDisplay()
的CellTreeWidget
。
因此,我的問題是:如果你
CellTree
, 並希望實現一種干凈的機制來更新數據和視圖,如何以正確的GWT方式進行?
不幸的是, CellTree
是一個非常復雜的小部件,與CellTable
或DataGrid
相比,它使用完全不同的概念。
這也是為什么它不像其他CellWidgets那樣阻礙HasData
接口的原因。
此外,通過CellTree
更新和刷新其節點並沒有得到足夠好的現成支持。 有幾種解決方法(請參閱此處和此處 )。 CellTree
擴展也試圖解決其中的一些問題( Project , Code , Demo )。
我建議先用CellTree
實現用例,然后再擔心它是否適合MVP
風格。 我已經告訴你,在處理CellTree
時,在View
和Presenter
之間繪制清晰的界限並不容易。
如果我正確理解了您的用例,那么您將擁有一個Container
對象列表(您正在使用CellList
嗎?),並且當您選擇一個特定的容器時,您想要顯示CellTree
中的項目列表並允許用戶編輯和添加/刪除項目。
我將嘗試強調重要步驟:
1.)您的數據結構與CellTree
不能很好地配合使用。 您應該引用每個項目的父項和子項列表:
public class Item
{
public int getItemId();
public Item getParent();
public List<Item> getChilds();
}
CellTree
與DataGrid
或CellTree
不同, CellTable
使用TreeViewModel
。
2.)定義一個自定義TreeViewModel
。
public class MyCustomTreeModel implements TreeViewModel {
private final SelectionModel<Item> selectionModel;
private final ValueUpdater<Item> valueUpdater;
public MyCustomTreeModel(final SelectionModel<Item> selectionModel, ValueUpdater<Item> valueUpdater) {
this.selectionModel = selectionModel;
this.valueUpdater = valueUpdater;
}
@Override
public <T> NodeInfo<?> getNodeInfo(final T value) {
// The root node is the container
ListDataProvider<Item> = new ListDataProvider<Item>();
if (value instanceof Container) {
provider.setList(((Container)value).getItemList();
return new DefaultNodeInfo<Item>(provider, containerCell, selectionModel,null);
}
provider.setList(((Item)value).getChilds());
return new DefaultNodeInfo<Item>(provider, itemCell, selectionModel, valueUpdater);
}
@Override
public boolean isLeaf(Object value) {
Item item = (Item) value;
return value != null && item.getChild().size() == 0;
}
}
3.)在View
實例化自定義MyCustomTreeModel
並使用選定的Container
實例創建CellTree
(選擇Container
,可以從Presenter
中進行創建:
public void onStartEdit(Container container, SelectionModel<Item> selectionModel, ValueUpdater<Item> valueUpdater) {
CellTree tee = new CellTree(new MyCustomTreeModel(selectionModel,valueUpdater));
}
同樣,您可能會遇到刷新問題,並且必須在TreeViewModel
中添加add()
和remove()
函數以添加和刪除項目。
查看鏈接的問題以獲取一些解決方法和代碼,我建議使用擴展的CellTree
。 如果可能,請使用其他小部件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.