【问题标题】:Vaadin 14 TreeGrid - Grid not loading hierarchyVaadin 14 TreeGrid - 网格不加载层次结构
【发布时间】:2021-01-28 13:09:27
【问题描述】:

我正在编写一个应用程序,它将显示逻辑上表示为项目层次结构集合的信息。将有一个“顶级”列表,将显示集合中所有根节点的名称。当其中一个项目被选中时,另一个列表(树形网格)将与所选的根节点一起加载,我需要它来显示并提供对其层次结构中所有内容的访问。

我不知道如何让层次结构加载到网格中。

我定义了一个扩展AbstractBackEndHierarchicalDataProvider 的数据提供者类。我的印象是,这个类的目的是促进以层次关系检索数据。我还有一个@Service 类,它从提供者那里调用来完成这项工作。代表节点的类 (TaskMaster) 不包含对“父”或“子”的任何引用。

代码如下:

TaskTreeView.java

public class TaskTreeView extends VerticalLayout {
  private TreeGrid<TaskMaster>   taskGrid;
  private TaskMasterDataProvider provider;
  private TaskMasterService      taskService;

  public TaskTreeView(TaskMasterService taskService) {
    this.taskService = taskService;
  }

  // Load the selected task (and its hierarchy).
  public void loadTasks(TopLevelTaskView.TaskSelectionEvent event) {
    if (event.getSelected() != null) {
      updateTree(event.getSelected());
    }
  }

  private void updateTree(TaskMaster task) {
    taskGrid.setItems(task);
    provider.refreshItem(task, true);
  }

  private void configureView() {
    taskGrid = new TreeGrid<>(TaskMaster.class);
    taskGrid.setColumns("name", "type");
    taskGrid.setHierarchyColumn("name");
    taskGrid.getColumns().forEach(col -> {
      col.setAutoWidth(true);
      col.setResizable(true);
    });

    provider = new TaskMasterDataProvider(taskService);
    taskGrid.setDataProvider(provider);
    add(taskGrid);
  }
}

TaskMasterDataProvider.java

public class TaskMasterDataProvider
    extends AbstractBackEndHierarchicalDataProvider<TaskMaster, Void> {
  private TaskMasterService service;

  public TaskMasterDataProvider(TaskMasterService service) {
    this.service = service;
  }

  @Override
  public int getChildCount(HierarchicalQuery<TaskMaster, Void> query) {
    return service.getChildCount(query.getParent());
  }

  @Override
  public boolean hasChildren(TaskMaster item) {
    return service.hasChildren(item);
  }

  @Override
  protected Stream<TaskMaster> fetchChildrenFromBackEnd(HierarchicalQuery<TaskMaster, Void> query) {
    return service.getChildren(query.getParent()).stream();
  }
}

TaskMasterService.java

@Service
@Transactional
public class TaskMasterService {
  private final TaskMasterRepository    taskMasterRepo;
  private final TaskRelationshipService taskRelationService;

  @Autowired
  public TaskMasterService(TaskMasterRepository taskMasterRepo,
      TaskRelationshipService taskRelationService) {
    this.taskMasterRepo = taskMasterRepo;
    this.taskRelationService = taskRelationService;
  }

  ...
  
  public int getChildCount(TaskMaster parent) {
    return parent != null
        ? taskRelationService.getChildRelationsForParent(parent.getInternalTaskID()).size()
        : 0;
  }

  public boolean hasChildren(TaskMaster parent) {
    return parent != null
        ? !taskRelationService.getChildRelationsForParent(parent.getInternalTaskID()).isEmpty()
        : false;
  }

  public List<TaskMaster> getChildren(TaskMaster parent) {
    List<TaskMaster> result = new ArrayList<>();

    if (parent != null) {
      List<TaskRelationship> childRelations = taskRelationService
          .getChildRelationsForParent(parent.getInternalTaskID());

      childRelations.forEach(relation -> {
        result.add(taskMasterRepo.findByInternalTaskID(relation.getChildTaskID()));
      });
    }

    return result;
  }
}

当我运行应用程序并从“顶级”列表中选择一个项目时,树会加载根节点,而不会加载其他任何内容。我是否以错误的方式使用提供程序?

域数据解释(据我所知):

任务大师

包含有关“任务”的信息,这是对许多事物的广泛描述,但主要用于定义应用程序菜单结构。任务类型是以下之一:TASK_VIEW、INTERACTIVE、BATCH、FOLDER、URL、USER_DEFINED。唯一 ID 是 internalTask​​ID。请注意,这不是数据库键。 此数据结构中没有“父”或“子”的概念。

任务关系

包含两个“任务”(即 TaskMaster 实体)之间的父/子关系。

例子:

在TaskMaster中:

{
    internalTaskID: "1014",
    name: "Manufacturing Tasks",
    type: "00", // TASK_VIEW
}

{
    internalTaskID: "464E4534",
    name: "Manufacturing Inquiries",
    type: "07", // FOLDER
}

{
    internalTaskID: "4E3CBF33",
    name: "Item Ledger",
    type: "01", // INTERACTIVE
}

在任务关系中:

{
    parentTaskID: "1014",
    childTaskID: "464E4534",
}

{
    parentTaskID: "464E4534",
    childTaskID: "4E3CBF33",
}

【问题讨论】:

  • 你能提供一个最小的工作示例(例如在 GitHub 上),我可以尝试一下吗?我假设 getChildCount 是错误的,因为如果父项为 null 则返回 0 但 parent == null 的项是根元素并且肯定有子项
  • 我已将项目添加到github。试试github.com/jgagnon44/e1-task-info-alt.git
  • 它是多模块 Maven。您可能需要做一些工作才能在数据库中获取一些数据。
  • 您的项目无法编译。 com.fossfloors:excel-to-json:jar:0.0.1-SNAPSHOT 丢失
  • 糟糕,很抱歉。我已将另一个项目添加到 github。 github.com/jgagnon44/excel-to-json.git

标签: java vaadin


【解决方案1】:

你的问题是这些方法:

  public int getChildCount(TaskMaster parent) {
    return parent != null
        ? taskRelationService.getChildRelationsForParent(parent.getInternalTaskID()).size()
        : 0;
  }

  public boolean hasChildren(TaskMaster parent) {
    return parent != null
        ? !taskRelationService.getChildRelationsForParent(parent.getInternalTaskID()).isEmpty()
        : false;
  }

如果您位于树的根元素上,则父元素始终为空。在这种情况下,您不必返回 false 或 0。

如果您位于没有父元素的根元素上,则必须在方法hasChildren 中返回true,并在getChildCount 中返回根元素的子元素数

【讨论】:

  • 这样做的问题是,唯一一次调用getChildCount() 方法时,传入的parent 始终为null。我无法获得不存在的东西的孩子数量。其他方法都没有被调用过。为什么?有人能解释一下这个东西应该如何工作和使用吗?
  • 如果传入的父项为null,则不应返回0。在这种情况下,您应该返回根项的总数。因此,您可以在服务中编写另一个方法,例如 int countAllRootTasks() 并返回值,而不是返回 0。
猜你喜欢
  • 1970-01-01
  • 2023-03-21
  • 2012-10-02
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 2021-09-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多