应该在 p:tree 到 select 树节点上使用什么事件并具有上下文菜单?

What event should be used on a p:tree to select a tree node and have a context menu?

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

我正在关注 example in the PrimeFaces showcase。如您所见,在 PrimeFaces 展示柜中,您可以立即右键单击一个节点,单击 "View",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。此问题已关闭为 "won't fix",评论为 "Please use contextMenu event"。

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

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

5.3 java-source and 5.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 但它 accepts/needs 一个 NodeSelectEvent