【问题标题】:PrimeFaces Tree component, setting selected node from managed beanPrimeFaces Tree 组件,设置从托管 bean 中选择的节点
【发布时间】:2012-05-22 18:03:11
【问题描述】:

我在 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;  
}  
}

有人知道怎么做吗?

【问题讨论】:

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

标签: jsf primefaces


【解决方案1】:

我解决了这个问题:

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

【讨论】:

  • 代码node.setSelected(true);应该在哪里?它在 View 或 Java Back bean 中 @jlago
【解决方案2】:

从支持 bean 调用树小部件组件上的 selectNode() 方法突出显示客户端上选定的树节点。

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

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

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

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

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

最后,从 backing 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】:

    对我来说,以上都不起作用。 因为从我在控制台中看到的内容来看,子节点没有任何 ID,更不用说任何行键号 所以我在 rowKey 属性的帮助下使用了 jQuery 高级类选择器 所以我不得不使用

    String script = "PF('treeSingleWidget').selectNode($(\"td[data-rowkey='" + selectedNode.getRowKey() + "']\"))";
    Primefaces.current().executeScript(script);
    

    【讨论】:

    • 我认为这是解决由不同问题引起的问题的方法。解决这个问题应该会更好
    【解决方案4】:

    在上述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。我不知道是否有区别。

    注册

    提姆

    【讨论】:

      【解决方案5】:

      请在treeBean.setSelectedNode(node);下方添加node.setSelected(true),它应该可以工作。

      【讨论】:

        【解决方案6】:

        尝试使用 primefaces 5.2 和多选:

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

        有效。

        【讨论】:

          【解决方案7】:

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

          通过 myTreeNode.setSelected(true);

          自动选择了 treeNode

          示例:

           for (TreeNode m2:root.getChildren())   {
          
                   if (((Menu) m2.getData()).getId() != null) {
          
                      if (me.getId().equals(((Menu) m2.getData()).getId())) {
          
                                                      m2.setSelected(true);
                                                      break;
                                                  }
                                              }
                                          }
          

          【讨论】:

          • 选中的集合不一样。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-03
          • 1970-01-01
          • 2013-05-02
          相关资源
          最近更新 更多