我正在尝试使用带有<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 />
会加载我请求的页面/块<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 />
将加载,树节点会突出显示?
提前致谢。
答案 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罐子的情况:)