Primefaces树 - 选择未在<pi> layout>中使用<ui:include> </ui:include> </p:layout>更新

时间:2011-05-24 23:53:58

标签: jsf-2 primefaces

我正在尝试使用带有<p:layout /><ui:include />的导航树,我想在点击树节点时动态更新<ui:include />

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui">
<f:view contentType="text/html">
<h:head></h:head>
<h:body>
<p:layout fullPage="true">
   <p:layoutUnit position="left" width="200" resizable="true" collapsible="true">
      <h:form>
         <p:tree expanded="true" nodeSelectListener="#{menutree.onTreeNodeClicked}" id="tree"
               value="#{menutree.menuTree}" var="node" update="test,tree"
               selection="#{menutree.selectedNode}" selectionMode="single">
            <p:treeNode>
               <h:outputText value="#{node}" />
            </p:treeNode>
         </p:tree>
      </h:form>
   </p:layoutUnit>
       <p:layoutUnit position="center" resizable="true" collapsible="false">
      <h:panelGroup id="test" layout="block">
         <ui:include src="${menutree.selectedNode.name}.xhtml" />
      </h:panelGroup>
   </p:layoutUnit>
</p:layout>
</h:body>
</f:view>
</html>

支持bean看起来像这样:

@SessionScoped
public class MenuTreeBean implements Serializable
{
    private final Log logger = LogFactory.getLog(getClass());

    private final TreeNode root;

    private TreeNode selectedNode;

    public MenuTreeBean()
    {
        root = new DefaultTreeNode("root", null);

        CustomTreeNode aaRoot = new CustomTreeNode("welcome", "Widgets", root);

        new CustomTreeNode("1", "Editor", aaRoot);
        new CustomTreeNode("2", "Calendar", aaRoot);

        setSelectedNode(aaRoot);
    }

    public TreeNode getMenuTree()
    {
        return root;
    }

    public TreeNode getSelectedNode()
    {
        logger.info("Selected: " + selectedNode);
        return selectedNode;
    }

    public void setSelectedNode(TreeNode selectedNode)
    {
        logger.info("Selected: " + selectedNode);
        this.selectedNode = selectedNode;
    }

    public void onTreeNodeClicked(NodeSelectEvent e)
    {
        logger.info("Clicked: " + e.getTreeNode());
        selectedNode = e.getTreeNode();
    }
}

相应地,只有少数页面,只包含一个Primefaces小部件 - 或者只是HTML。

这在Web浏览器中提供了这样的布局:

------------------------------------
| Widget      |                    |
|   Editor    |                    |
|   Calendar  |                    |
|             |                    |
|             |                    |
|             |                    |
|             |                    |
|             |                    |
|             |                    |
------------------------------------

我遇到的问题是

  • 当我点击上面的编辑器节点时,它会被选中并突出显示,而<ui:include />会加载我请求的页面/块
  • 当我点击上面的日历节点时,它会被选中并突出显示,而<ui:include />会加载我请求的页面/块
  • 当我单击上面的Editor节点时,它没有被选中,但<ui:include />仍然加载我请求的页面/块;日历节点仍然突出显示

如果我在<p:tree />处关闭更新属性,则树节点选择和突出显示按预期工作;除了我错过了我需要的动态<ui:include />

对于上面的日志记录,Widgets设置为最初选择。然后,当我单击Editor时,方法的顺序是

2011/05/24 23:06:25 com.foo.bar.MenuTreeBean getSelectedNode
INFO: Selected: Widgets
2011/05/24 23:06:25 com.foo.bar.MenuTreeBean getSelectedNode
INFO: Selected: Widgets
2011/05/24 23:06:25 com.foo.bar.MenuTreeBean setSelectedNode
INFO: Selected: Editor
2011/05/24 23:06:25 com.foo.bar.MenuTreeBean onTreeNodeClicked
INFO: Clicked: Editor
2011/05/24 23:06:25 com.foo.bar.MenuTreeBean getSelectedNode
INFO: Selected: Editor

但是当我点击日历时,序列变为

2011/05/24 23:07:15 com.foo.bar.MenuTreeBean getSelectedNode
INFO: Selected: Editor
2011/05/24 23:07:15 com.foo.bar.MenuTreeBean getSelectedNode
INFO: Selected: Editor
2011/05/24 23:07:15 com.foo.bar.MenuTreeBean setSelectedNode
INFO: Selected: Editor
2011/05/24 23:07:15 com.foo.bar.MenuTreeBean onTreeNodeClicked
INFO: Clicked: Calendar
2011/05/24 23:07:15 com.foo.bar.MenuTreeBean getSelectedNode
INFO: Selected: Calendar

我想知道是否遗漏了任何内容,以便当我点击树节点时,<ui:include />将加载,树节点会突出显示?

提前致谢。

3 个答案:

答案 0 :(得分:0)

我能理解你想要做什么,但我不一定认为这是最好的方法。

您应该查看主模板页面,而不是动态更改src标记的<ui:include属性,所有子页面都将继承其基本内容。

在模板页面中,您可以定义layoutUnit:

<p:layoutUnit position="center" scrollable="true">
  <ui:insert name="content">
  <!-- content would go here -->
  </ui:insert>
</p:layoutUnit>

然后在您的子页面中指定合成标记。

<ui:composition template="/WEB-INF/templates/master.xhtml">

现在,您的树节点而非动态更新src属性只能重定向到相应的URL,您的树节点和母版页内容将正确加载。

答案 1 :(得分:0)

我同意maple_shaft你应该使用模板。但是,如果您必须坚持这一点,请查看 p:tree 元素的更新属性。在那里,您指定要更新的元素的ID,可以是您的 ui:include 元素,因为它是一个UIComponent。

在我的应用程序中,我也使用 p:tree 进行导航,但我更喜欢在单击节点时强制重定向。这样做的原因是结果页面可由浏览器标记。换句话说,目标URL最终出现在浏览器地址文本框中。

我这样做的方法是在支持bean中,如下所示:

public void onNodeSelect(NodeSelectEvent event) {

    selectedNode = event.getTreeNode();
    String url =  // compute some URL to move to based on selectedNode

    FacesContext fc = FacesContext.getCurrentInstance();
    ExternalContext ec = fc.getExternalContext();
    try {
        ec.redirect(url);
    } catch (IOException ex) {
        Logger.getLogger(Navigation.class.getName()).log(Level.SEVERE, null, ex);
    }
}

重申:使用模板,即使这意味着您的学习曲线,它实际上会强制您的网络应用程序更具凝聚力和纪律性。

答案 2 :(得分:0)

最终我自己解决了这个问题。

事实证明,在Javascript中存在一些问题,当我向多个目的地指定<p:tree update="" />时,树节点不会突出显示。

因此,在阅读了代码和YUI文档之后,最后我通过向<p:tree />的onNodeClick处理程序添加Javascript函数来解决问题,强制突出显示所选节点。

该功能只强制突出显示点击的节点。

function highlightNode(e)
{
    e.node.highlight();
}

至少适用于使用官方Primefaces罐子的情况:)