Primefaces 树以及如何根据 TreeNode 叶子实体 ID 进行导航

Primefaces tree and how to navigate based on TreeNode leaf entity ID

我有 3 个实体 - 市场、主题和项目。市场是主题的父级,主题是项目的父级。我希望找到一种简单的方法来调用操作,方法是从最终子节点(项目)中选择一个值并将其带到可以查看所选项目的页面。 JSF:

 <p:tree value="#{treeTestBean.treeTest}" var="tree" 
                        dynamic="true" 
                        selectionMode="single" 
                        selection="#{treeTestBean.selectednode}">

                    <p:ajax event="select" listener="#{treeTestBean.onNodeSelect}"/>
                    <p:treeNode>
                        <h:outputText value="#{tree}"/>
                    </p:treeNode>
  </p:tree>  

托管 bean:

@Named(value = "treeTestBean")
@SessionScoped
public class TreeTestBean implements Serializable {

private TreeNode treetest;
private TreeNode selectednode;
private TreeNode node0;
private TreeNode node1;
private TreeNode node2;

private List<Enmarkets> markList;
private List<Entopic> topList;
private ListDataModel<Enitem> itList;

private Enitem selItem;

public TreeNode getTreeTest() {
    treetest = new DefaultTreeNode("Root", null);
    markList = rootFacade.findAll();

    for (Enmarkets m : markList) {

        node0 = new DefaultTreeNode(m.getMarketname(), treetest);
        int marketid = m.getMarketid();
        topList = topfac.marketTopNorm(marketid);

        for (Entopic t : topList) {
            node1 = new DefaultTreeNode(t.getTopicname(), node0);
            int topicid = t.getTopicid();
            itList = itfac.itemFroTopic(topicid);

            for (Enitem i : itList) {
                node2 = new DefaultTreeNode(i.getItemname(), node1);
            }

        }
    }

    return treetest;
}

ajax中使用的onNodeSelect方法也在托管bean中。如果所选节点是叶节点,它将搜索项目名称和导航页面中的 return:

public void onNodeSelect(NodeSelectEvent event) {
this.setSelectednode(event.getTreeNode());

String somekey = selectednode.getRowKey();

if(selectednode.isLeaf()){
    String itemName = selectednode.getData().toString();

// Standard JPA call to search for item name here (omitted because this is not how i want to do it)

    FacesContext
            .getCurrentInstance()
            .getApplication()
            .getNavigationHandler()
            .handleNavigation(FacesContext.getCurrentInstance(), null, "/Main/Starter.xhtml?faces-redirect=true");
}
else {
    doNothing();
}
}

onNodeSelect 应该搜索项目名称并导航到包含所选项目详细信息的页面。上述方法通过搜索项目名称字符串并将其与从持久层创建的项目实体值列表中的名称相匹配来实现。这将允许将 selectednode 字符串与正确的项目名称匹配,以便导航的 jsf 页面填充实体详细信息(例如使用标准 h:outputText 标记)。出于多种原因,我更喜欢基于实体 ID 而不是字符串进行搜索。

Kukeltje 的评论极大地帮助我找到了正确的方向。首先,我在创建叶节点时包含一个 Map(String, int):

for (Enitem i : itList) {
node2 = new DefaultTreeNode(i.getItemname(), node1);
String rowK = node2.getRowKey();
int itid = i.getItemid();
rowMap.put(rowK, itid);

然后,在 onNodeSelect 方法中,我使用此映射将所选节点的 rowKey 与相应的实体 Id 匹配:

public void onNodeSelect(NodeSelectEvent event) {

if(selectednode.isLeaf()){
String rKey = selectednode.getRowKey();
if(rowMap.containsKey(rKey)) {
String xKey = rowMap.get(rKey).toString();
Integer rKeyint = Integer.parseInt(xKey);
selItem = itfac.find(rKeyint);

FacesContext
.getCurrentInstance()
.getApplication()
.getNavigationHandler()
.handleNavigation(FacesContext.getCurrentInstance(), null, "/Main/Client/ItemDetails.xhtml?faces-redirect=true");

    }
}
else {
doNothing();
}

这将导航到显示所选节点叶的详细信息的页面。我怀疑可能有更简单或更有效的方法来做到这一点,并欢迎任何意见。就像,我不知道是否真的有必要将字符串转换为整数,而且我没有想出更简单的方法。

目前,这似乎解决了我的具体问题。谢谢