问题 PrimeFaces Tree组件,从托管bean设置选定节点


我在Glassfish 3上运行Primefaces 3.2和JSF 2.0。

我已经尝试了很多,以编程方式从托管bean中设置所选节点。这包括设置所选节点,如下所示:

public void setSelectedTreeNode(String name) {
TreeNode root = treeBean.getRoot();
List<TreeNode> tree = root.getChildren();
for(TreeNode node:tree) {
  if(node.getData().toString().contains(name)) {
    System.out.println("found the node to select");
    treeBean.setSelectedNode(node);
    break;
  }
}
RequestContext context = RequestContext.getCurrentInstance(); 
context.update(":navForm:treeSingle");
}

“找到要选择的节点”将在终端中打印,但在网页的树中未选择该节点。

树是这样的:

<h:form id="navForm">
<p:tree id="treeSingle" value="#{treeBean.root}" var="node"  
       selectionMode="single" styleClass="treeStyle" 
       selection="#{treeBean.selectedNode}"
       cache="false"
       >  
   <p:ajax event="select" listener="#{treeBean.onNodeSelect}" update=":mainForm" />
   <p:treeNode>  
       <h:outputText value="#{node}" escape="false" />  
   </p:treeNode>  

编辑:TreeBean是这样构建的:

@ManagedBean
@SessionScoped    
public class TreeBean implements Serializable {  

private TreeNode root;  

private TreeNode selectedNode;  

public TreeBean() {  
    root = new DefaultTreeNode("Root", null);  
    TreeNode node0 = new DefaultTreeNode("Node 0", root);  
    TreeNode node1 = new DefaultTreeNode("Node 1", root);  
    TreeNode node2 = new DefaultTreeNode("Node 2", root);  

    TreeNode node00 = new DefaultTreeNode("Node 0.0", node0);  
    TreeNode node01 = new DefaultTreeNode("Node 0.1", node0);  

    TreeNode node10 = new DefaultTreeNode("Node 1.0", node1);  
    TreeNode node11 = new DefaultTreeNode("Node 1.1", node1);  

    TreeNode node000 = new DefaultTreeNode("Node 0.0.0", node00);  
    TreeNode node001 = new DefaultTreeNode("Node 0.0.1", node00);  
    TreeNode node010 = new DefaultTreeNode("Node 0.1.0", node01);  

    TreeNode node100 = new DefaultTreeNode("Node 1.0.0", node10);  
}  

public TreeNode getRoot() {  
    return root;  
}  

public TreeNode getSelectedNode() {  
    return selectedNode;  
}  

public void setSelectedNode(TreeNode selectedNode) {  
    this.selectedNode = selectedNode;  
}  
}

有没有人知道如何做到这一点?


3822
2018-05-15 08:46


起源

treeBean.setSelectedNode(node)做了什么?你能展示那种方法的代码吗? - Damian
使用TreeBean更新了问题。它基本上只是一个普通的制定者。像这样建造: primefaces.org/showcase/ui/treeSelectionSingle.jsf - baron5
好。 setSelectedTreeNode方法在另一个bean中吗?豆子的范围是什么?你使用ManagedProperty注入?你确定注入的treeBean是页面使用的treeBean吗? (也许正在创建一个新实例) - Damian
实际上是一个有趣的问题。 bean是SessionScoped,但我正在编辑一个从JSF 1.1升级到JSF 2.0的旧应用程序,因此我使用的是旧的FacesContext facesContext = FacesContext.getCurrentInstance(); VariableResolver vr = facesContext.getApplication()。getVariableResolver(); TreeBean treeBean =(TreeBean)vr.resolveVariable(facesContext,“TreeBean”);而不是注射。也许有什么东西.. - baron5
我建议你调试或添加一些日志记录来确定是否使用了相同的实例。也许你的代码创建了一个新实例。你也可以尝试使用@ManagedProperty(value =“#{treeBean}”而不是JSF 1.1代码 - Damian


答案:


我解决了它:

node.setSelected(true);

我发现选择节点不足以使“树组件”从根节点扩展到选定节点。

为此,我使用了以下方法。在视图上:

 <p:ajax event="expand" listener="#{tree.onExpand}"/>

在java代码上:

public void onExpand(NodeExpandEvent event) {
    expand(event.getTreeNode());
}

private void expand(TreeNode treeNode){
    if (treeNode.getParent()!=null){
        treeNode.getParent().setExpanded(true);
        expand(treeNode.getParent());
    }
}

12
2018-06-10 13:29



应该在哪里代码 node.setSelected(true); ?它位于View或Java Back bean @jlago中 - Mazy


要从客户端侧突出显示选定的树节点,请在树窗口小部件组件上调用selectNode()方法。

首先,将widget var属性设置为jsf树组件:

<p:tree id="treeSingle" widgetVar="treeSingleWidget"

您可以从浏览器控制台测试它:

PrimeFaces.widgets.treeSingleWidget.selectNode($("#treeSingle\\:1"), true);

第一个方法参数表示通过它的id获取的节点jquery对象(冒号符号必须由两个反斜杠转义)。 如果第二个参数设置为false,则将触发节点选择事件。

最后,从支持bean调用javascript:

StringBuilder sb = new StringBuilder();
    sb.append("PrimeFaces.widgets.treeSingleWidget.selectNode(");
    sb.append("$(\"#treeSingle\\\\:");
    sb.append(selectedNode.getRowKey());
    sb.append("\")");
    sb.append(", true)");
    RequestContext.getCurrentInstance().execute(sb.toString());

附:在浏览器控制台中发现组件js api类型

PrimeFaces.widget.VerticalTree.prototype

3
2017-09-08 02:31





在上面 if 陈述,如果是真的,做一个 node.setSelected(true);

我用它来根据需要设置节点。反过来显然有相反的效果;它会把它们关掉。我的用例是一个布尔复选框,可以打开或关闭所有节点,因为我有很多节点在树的一侧运行。因此,我的实际代码涉及一些方法:

public Boolean getSelectionState() {
    return selectionState;
}

public void setSelectionState(Boolean selectionState) {
    this.selectionState = selectionState;
}

public String getSelectLabel() {
    return selectionState ? "De-select all" : "Select all";
}

/**
 * Flips all nodes on or off depending on checkbox.
 */
public void onSelectChange() {
    if (prefs.isDebug()) {
        LOG.log(Level.INFO, "Value change event occured. Selection state is:{0}", selectionState);
    }
    for (TreeNode node : rootNode.getChildren()) {
        node.setSelected(selectionState);
    }
    nodes = new ArrayList(rootNode.getChildren());
    selectedNodes = nodes.toArray(new TreeNode[nodes.size()]);
    mapDevices();
}

然而,我在GF 3上的JSF 2上使用3.4。我不知道是否存在差异。

REGS

蒂姆


1
2017-12-27 20:35





请加 node.setSelected(true) 下面 treeBean.setSelectedNode(node); 它应该工作。


1
2018-04-05 14:31





尝试使用primefaces 5.2和多选:

treeBean.setSelectedNode(new TreeNode[]{node});

作品。


0
2017-07-08 15:25





我正在使用Glassfish 3.1 Build 43中部署的Primefaces 3.0;

已经或者自动选择了treeNode: myTreeNode.setSelected(真);

示例: 

 for (TreeNode m2:root.getChildren())   {

         if (((Menu) m2.getData()).getId() != null) {

            if (me.getId().equals(((Menu) m2.getData()).getId())) {

                                            m2.setSelected(true);
                                            break;
                                        }
                                    }
                                }

-1
2017-10-12 09:09



这与5个upvotes的答案相同...... - Kukeltje
在选定的集合中不一样。 - bilelovitch