Дерево Primefaces динамически добавляет братьев и сестер / детей через commandButtons - PullRequest
0 голосов
/ 07 ноября 2019

Я пытаюсь реализовать динамическую древовидную структуру в простых лицах, где пользователь, начиная с root node, сможет добавить siblings и children в каждый узел через два commandButtons.

* 1006. * Пример показан ниже:

Root

Root

После добавления брат и сестра нажали

ROOT sibling

После добавления ребенка нажимается (2 раза)

enter image description here

После этого я реализовал следующую структуру:

tree.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>

TreeController

     @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);
        }
}

Однако при нажатии кнопок я получаю SEVERE [org.primefaces.application.exceptionhandler.PrimeExceptionHandler] (default task-6) Method not found: TreeController.addSibling(java.lang.String), что вызвано тем, что функции ожидают получения параметра String (узла).

Есть ли способ получить ссылку TreeNode на слушателей кнопок?

Может быть, любой NodeEvent вроде NodeExpandEvent?

PS: Я использую Primefaces 7.0 с JSF 2.1

1 Ответ

2 голосов
/ 07 ноября 2019

Согласно документации атрибута p: tree var:

Имя переменной в области запроса, которая будет использоваться для ссылки на каждый триод data .

Это первый аргумент, который вы передаете конструктору узла:

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>
...