gpt4 book ai didi

java - 如何在 GWT 中为 CellTree 正确实现 MVP?

转载 作者:行者123 更新时间:2023-12-02 05:36:13 27 4
gpt4 key购买 nike

假设我有一个类CellTreeWidget ,其中包含 CellTree .

我想写一个与交互的演示者

  1. CellTreeWidget实例和
  2. 用于获取数据的远程服务。

数据显示在 CellTreeWidget是一个项目列表。每个项目都有一个父项目并属于一个容器。

public class Container
{
public List<Item> getItemList();
public void setItemList(List<Item> aItemList);
}

public class Item
{
public int getItemId();
public int getParentItemId();
}

有以下涉及演示者的流程:

  1. 用户选择一个容器(请参阅下面的 Presenter.startEdit)。
  2. 用户保存对容器所做的更改(请参阅下面的 Presenter.save)。

当用户选择容器时,CellTreeWidget必须更新以显示新选择的容器的项目。

当用户保存对容器所做的更改时,演示者必须

  1. 向远程服务发送保存请求并
  2. 如果请求已正确处理,请确保树中的项目已更新。

第 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实现接口(interface)View ,其定义如下:

public interface View extends IsWidget, HasSelectionChangedHandlers {
HasData<Item> getDisplay();
}

这种方法的问题是我没有看到明显的方法来提供方法 HasData<Item> getDisplay() 的实现在 CellTreeWidget类。

因此我的问题是:如果你

  1. 具有树状结构,即
  2. 显示在CellTree中,
  3. 可以在客户端(用户添加新项目)和
  4. 上进行修改
  5. 在服务器上(新项目保存在数据库中并获取新 ID)

并且想要实现一个干净的机制来更新数据和 View ,如何才能以正确的 GWT 风格方式完成?

最佳答案

免责声明

不幸的是,CellTree 是一个相当复杂的小部件,与 CellTableDataGrid 相比,它使用完全不同的概念。
这也是它不像其他 CellWidget 那样实现 HasData 接口(interface)的原因。

此外,CellTree 更新和刷新其节点并没有得到很好的开箱即用支持。有几种解决方法(请参阅 herehere )。还有 CellTree 的扩展尝试修复其中一些问题( ProjectCodeDemo )。

我建议首先使用 CellTree 实现您的用例,然后再考虑它是否适合 MVP 风格。我已经可以告诉您,在处理 CellTree 时,在 ViewPresenter 之间划出清晰的界限并不容易。

您的用例

如果我正确理解了您的用例,您有一个 Container 对象列表(您使用的是 CellList 吗?),当您选择所需的特定容器时显示 CellTree 中的项目列表并允许用户编辑和添加/删除项目。

我将尽力强调重要步骤:

1.) 您的数据结构并不能很好地与 CellTree 配合使用。您应该引用每个项目的父级和子级列表:

public class Item
{
public int getItemId();
public Item getParent();
public List<Item> getChilds();
}

CellTreeDataGridCellTable 不同,使用 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 (当您选择容器时,您可以从 Presenter 中进行操作:

public void onStartEdit(Container container, SelectionModel<Item> selectionModel, ValueUpdater<Item> valueUpdater) {
CellTree tee = new CellTree(new MyCustomTreeModel(selectionModel,valueUpdater));
}

摘要

您可能会再次遇到刷新问题,并且您必须向您的 TreeViewModel 添加 add()remove() 函数> 用于添加和删除项目。

查看链接问题中的一些解决方法和代码,我建议使用扩展的 CellTree。如果可能,请使用不同的小部件。

关于java - 如何在 GWT 中为 CellTree 正确实现 MVP?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24936431/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com