应该在p:树上使用什么事件来选择树节点并具有上下文菜单?

时间:2016-03-04 09:44:40

标签: jsf primefaces tree contextmenu

我正在使用上下文菜单创建PrimeFaces(5.3)树。选定的节点应存储在#{myBean.selectedNode}中。当我使用鼠标左键选择节点时,设置了正确的节点。但是,当我尝试从上下文菜单中运行某个节点上的操作时,而不先选择它,正确的节点没有设置(我的bean中的setter没有被调用)。 / p>

我跟随example in the PrimeFaces showcase。如您所见,在PrimeFaces展示中,您可以立即右键单击节点,单击"查看",然后growl将显示正确的节点。

这是我的设置:

它是ViewScoped,并且有一个private TreeNode selectedNode有getter和setter。

以下是有趣的内容:

public void onNodeSelect(NodeSelectEvent event) {
    MyTreeNode myTreeNode = (MyTreeNode) event.getTreeNode();
    myController.setSelected(myTreeNode.getEntity());
}

public void addChild(String name) {
    MyTreeNode myTreeNode = (MyTreeNode) selectedNode;
    MyTreeNode childNode = myTreeNode.addChild(name);
    myController.setSelected(childNode.getEntity());
    myController.insert();
}

XHTML

<h:form id="mainForm">
    <p:tree value="#{myBean.root}" var="node"
            id="myTree" dynamic="true"
            selectionMode="single" selection="#{myBean.selectedNode}">
        <p:treeNode expandedIcon="ui-icon-folder-open" collapsedIcon="ui-icon-folder-collapsed"
                    type="myType">
            <h:outputText value="#{node}"/>
        </p:treeNode>
        <p:ajax event="select" listener="#{myBean.onNodeSelect}" />
    </p:tree>

    <p:contextMenu for="myTree">
        <p:menuitem action="#{myBean.addChild('new')}"
                    value="Add"
                    process="@this"
                    update=":mainForm:myTree"/>
    </p:contextMenu>
</h:form>

我能够通过替换JavaScript中的PrimeFaces.widget.BaseTree.nodeRightClick函数来解决此问题,以便在右键单击时触发fireNodeSelectEvent

PrimeFaces.widget.BaseTree.prototype.nodeRightClick = function(e, a) {
    PrimeFaces.clearSelection();
    if ($(e.target).is(":not(.ui-tree-toggler)")) {
        var d = a.parent(), b = a.hasClass("ui-tree-selectable");
        if (b && this.cfg.selectionMode) {
            var c = this.isNodeSelected(d);
            if (!c) {
                if (this.isCheckboxSelection()) {
                    this.toggleCheckboxNode(d)
                } else {
                    this.unselectAllNodes();
                    // Fixed right click selecting
                    // original code: this.selectNode(d, true)
                    this.selectNode(d); // <-- Fix
                }
            }
            this.fireContextMenuEvent(d)
        }
    }
}

这对我来说似乎是一个错误,所以我在GitHub上创建了一个issue。这个问题已经关闭,因为&#34;不会修复&#34;评论&#34;请使用contextMenu事件&#34;。

我已经两次检查了文档的树和contextMenu部分。什么事件应该在哪里使用?我在GitHub上提出asked同样的问题,但没有回复。

1 个答案:

答案 0 :(得分:8)

阅读issue you reported,我调查了代码( 打开)。似乎p:tree有一些未记录的事件,contextMenu是其中之一(dragdrop是另一个)。

5.3 java-source5.3 javascript-source包含对contextMenu事件的引用,所以

<p:ajax event="contextMenu" listener="#{myBean.onContextMenu}" />

public void onContextMenu(NodeSelectEvent event) {
    MyTreeNode myTreeNode = (MyTreeNode) event.getTreeNode();
    myController.setSelected(myTreeNode.getEntity());
}

会奏效。请注意,没有ContextMenuEvent但它接受/需要NodeSelectEvent