1

Vaadin を使用して、「タスク」のツリーを表示するアプリケーションを作成しようとしていますTreeGrid

注意すべき非常に重要なことは、ツリー ノード タイプには親または子への参照が含まれていないことです。代わりに、個別のタイプに親子関係が含まれ、ツリー ノード タイプの項目の一意の ID を参照します。

これら 2 つのタイプは、独自のデータベース テーブルに別々に格納されます。データ自体は、MS Excel ファイルから抽出され (理由は聞かないでください)、アプリケーションがデータへのアクセスに使用するデータベースに挿入されました。

これをより視覚的に表現するには:

TaskMaster (ツリー ノード タイプ):

@Entity
public class TaskMaster extends AbstractEntity {

  private String   internalTaskID;
  private String   name;
  private TaskType type;
  // other fields

  ...
}

TaskRelationship (親子関係):

@Entity
public class TaskRelationship extends AbstractEntity {

  private String  taskView;
  private String  parentTaskID;
  private String  childTaskID;
  // other fields

  ...
}

必要に応じて情報を簡単に取得できるようにクラスを作成@Repositoryしました。@Service

グリッドをロードして、タスク ツリーを表すノードの階層を表示する方法がわかりません。私は Vaadin の例を見て、このデータをロードしようとするデータ プロバイダーを作成しましたが、役に立ちませんでした。ルート ノードのみをロードし、他には何もロードしません。

ノード オブジェクトに親と子への参照が含まれている場合、ツリー グリッドだけが階層関係を処理する方法を知っているのではないかと考えています。私のオブジェクトはこれを行いません。代わりに、必要なものを「取得」するために、サービスおよびデータ プロバイダー クラスにロジックを設定しようとしました。どうやらそれはうまくいきません。それか、本当に微妙なものが欠けています。

これが私の努力を表すコードの一部です。

TaskMasterDataProvider:

public class TaskMasterDataProvider
    extends AbstractBackEndHierarchicalDataProvider<TaskMaster, Void> {

  ...

  @Override
  public int getChildCount(HierarchicalQuery<TaskMaster, Void> query) {
    logger.info("parent: {}", query.getParent());

    if (query.getParent() != null) {
      int count = service.getChildCount(query.getParent());
      logger.info("child count: {}", count);
    }

    return service.getChildCount(query.getParent());
  }

  @Override
  public boolean hasChildren(TaskMaster item) {
    logger.info("item: {}", item);
    return service.hasChildren(item);
  }

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

}

TaskMasterService:

@Service
@Transactional
public class TaskMasterService {

  ...
    
  public List<TaskMaster> getTopLevelTasks() {
    List<TaskMaster> result = new ArrayList<>();
    List<String> topLevelIDs = taskRelationService.getTopLevelParentTaskIDs();

    topLevelIDs.forEach(id -> {
      TaskMaster task = taskMasterRepo.findByInternalTaskID(id);

      if (task != null) {
        result.add(task);
      }
    });

    return result;
  }

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

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

  public List<TaskMaster> getChildren(TaskMaster parent) {
    logger.info("parent: {}", 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;
  }

}

TaskTreeView:

@Route("tree")
@CssImport("./styles/shared-styles.css")
public class TaskTreeView extends VerticalLayout {

  ...
  private TreeGrid<TaskMaster>   taskGrid;
  private TaskMasterDataProvider provider;

  private TaskMasterService      taskService;

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

    setSizeFull();
    addClassName("task-tree-grid");

    configureView();
  }
    
  private void configureView() {
    taskGrid = new TreeGrid<>();
    taskGrid.addHierarchyColumn(TaskMaster::getName).setHeader("Name");
    taskGrid.addColumn(TaskMaster::getType).setHeader("Type");

    taskGrid.getColumns().forEach(col -> {
      col.setAutoWidth(true);
      col.setResizable(true);
    });

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

    taskGrid.asSingleSelect().addValueChangeListener(event -> {
      if (event.getValue() != null) {
        provider.refreshItem(event.getValue(), true);
      }
    });

    add(taskGrid);

    taskGrid.setItems(taskService.getTopLevelTasks());
  }
    
}

これがすべてではありませんが、最も重要なことだと思います。必要に応じてさらに追加できます。

私の理論に何らかのメリットがあるかどうか、または私が何か完全に間違っているかどうかについて誰かが洞察を持っている場合は、お知らせください.

4

2 に答える 2