首页 > 解决方案 > Primefaces树通过commandButtons动态添加兄弟/子

问题描述

我正在尝试在 primefaces 中实现一个动态树结构,其中用户从 a 开始,root node将能够通过两个.siblingschildrencommandButtons

示例如下所示:

根

添加同级后按下

ROOT 兄弟

添加孩子后按下(2次)

在此处输入图像描述

之后,我实现了以下结构:

树.xhtml

<p:tree id="tree" value="#{treeController.root}" 
    var="node" dynamic="true" cache="false">
    <p:ajax event="expand" listener="#{treeController.onNodeExpand}" />
    <p:treeNode>
       <h:outputText value="#{node}" />
       <p:commandButton style="width:50%; margin: 10px;" value="Add Sibling">
           <p:ajax event="click" listener="#{treeController.addSibling(node)}" update="@this"> 
           </p:ajax>
       </p:commandButton>
       <p:commandButton style="width:50%; margin: 10px;" value="Add Child">
           <p:ajax event="click" listener="#{treeController.addChild(node)}" update="@this"> 
           </p:ajax>
       </p:commandButton>
    </p:treeNode>
</p:tree>

树控制器

     @ManagedBean(name = "treeController")
     @ViewScoped
     public class TreeController implements Serializable {

        private TreeNode root; //getters && setters ommitted

        @PostConstruct
        public void buildTree() {
            this.root = new DefaultTreeNode("Root", null);
            createNode("ROOT", this.root);
        }

        public void onNodeExpand(NodeExpandEvent event) {
            DefaultTreeNode parent = (DefaultTreeNode) event.getTreeNode();
            if (parent.getChildCount() == 1 && parent.getChildren().get(0).getData().toString().equals("ROOT")) {
                parent.getChildren().remove(0);
                createNode(parent.getData().toString()+ "'s Child " + (parent.getChildren().size() + 1), parent);
                createNode(parent.getData().toString()+ "'s Child " + (parent.getChildren().size() + 1), parent);
            }
        }

        public void addSibling(TreeNode node){
            // I need here the corresponding TreeNode element to add to it's parent a new TreeNode
        }

        public void addChild(TreeNode node){
            // I need here the corresponding TreeNode element to add into it a new child
        }

        private void createNode(String tag, TreeNode parent) {
            TreeNode node = new DefaultTreeNode(tag, parent);
            // Create Dummy node, just to make the parent node expandable
            new DefaultTreeNode("ROOT", node);
        }
}

但是,我得到的按钮的 onclickSEVERE [org.primefaces.application.exceptionhandler.PrimeExceptionHandler] (default task-6) Method not found: TreeController.addSibling(java.lang.String)是由于函数期望接收字符串参数(节点)而引起的。

有没有办法在按钮的侦听器上检索 TreeNode 引用?

也许像任何 NodeEvent 一样NodeExpandEvent

PS:我正在Primefaces 7.0使用JSF 2.1

标签: jsfprimefacestreetreenode

解决方案


根据p:tree var属性的文档:

将用于引用每个树节点数据的请求范围变量的名称。

这是您传递给节点构造函数的第一个参数:

org.primefaces.model.DefaultTreeNode.DefaultTreeNode(Object data, TreeNode parent)

从您的代码中可以看出,它的异常类型为String.

如果要引用实际节点,请在nodeVar属性旁边使用属性而不是 / var

nodeVar:请求范围变量的名称,该变量将用于使用 EL 引用当前树节点。

在您的情况下,您可以像这样修改示例:

<p:tree id="tree" value="#{treeController.root}" 
    var="node" nodeVar="theNode" dynamic="true" cache="false">
    <p:ajax event="expand" listener="#{treeController.onNodeExpand}" />
    <p:treeNode>
       <h:outputText value="#{node}" />
       <p:commandButton style="width:50%; margin: 10px;" value="Add Sibling" 
        action="#{treeController.addSibling(theNode)}" update="@this" />
       <p:commandButton style="width:50%; margin: 10px;" value="Add Child"  
        action="#{treeController.addChild(theNode)}" update="@this" />
    </p:treeNode>
</p:tree>

推荐阅读