java 使用 Primefaces 呈现部分页面 - JSF 2.0 导航
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5807384/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Partial page rendering with Primefaces - JSF 2.0 navigation
提问by Yasin Bahtiyar
I am trying to create a facelet page which updates <ui:insert>
elements with ajax calls. Whenever a <p:commandButton action="next"/>
is clicked ajax call should take place and only <ui:insert>
parts of the facelet template should be updated. My question is exactly same as the question in herebut the solution over there does not work. Furthermore, considering the comment, it is quite ambiguous if the answer is accepted or not. I am stuck without any solution and not sure if this is related to PrimeFaces FAQ#4
我正在尝试创建一个<ui:insert>
使用 ajax 调用更新元素的 facelet 页面。每当<p:commandButton action="next"/>
单击 ajax 调用时,应该只<ui:insert>
更新 facelet 模板的一部分。我的问题与这里的问题完全相同,但那里的解决方案不起作用。此外,考虑到评论,答案是否被接受是非常模棱两可的。我没有任何解决方案,不确定这是否与PrimeFaces 常见问题解答有关#4
I have another solution proposal with <ui:import>
but not quite sure if this is a good solution. I am storing active page in a bean attribute and updating the value with ajax calls. So any comments and/or ideas are more than appreciated.
Here is my proposal:
我有另一个解决方案建议,<ui:import>
但不太确定这是否是一个好的解决方案。我将活动页面存储在 bean 属性中并使用 ajax 调用更新值。所以任何评论和/或想法都非常感谢。这是我的建议:
template.xhtml
模板.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title><ui:insert name="title" />
</title>
</h:head>
<h:body>
<div id="wrapper">
<div id="header">Primafaces Partial Page Update navigation</div>
<h:panelGroup id="content" layout="block">
<ui:insert name="content">
Sample content.
</ui:insert>
</h:panelGroup>
</div>
<div id="footer">Made using JSF & Primefaces</div>
</h:body>
</html>
main.xhtml
主文件
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui" template="template.xhtml">
<ui:define name="title">Main page</ui:define>
<ui:define name="content">
<ui:include src="#{navBean.activePage}" />
</ui:define>
</ui:composition>
NavigationBean.java
导航Bean.java
@Component("navBean")
@Scope("session")
public class NavigationBean implements Serializable{
private String activePage="firstAjax.xhtml";
public String getActivePage() {
return activePage;
}
public void setActivePage(String activePage) {
this.activePage = activePage;
}
public void next(ActionEvent e) {
this.setActivePage("lastAjax.xhtml");
}
public void back(ActionEvent e) {
this.setActivePage("firstAjax.xhtml");
}
}
firstAjax.xhtml
第一个Ajax.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h2>First Page!</h2>
<h:form>
<p>Click the button to go to next page!</p>
<p:commandButton value="Next"
actionListener="#{navBean.next}" update=":content" />
</h:form>
</ui:composition>
lastAjax.xhtml
lastAjax.xhtml
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui">
<h2>Last Page!</h2>
<h:form>
<p>Click the Back button to go to previous page!</p>
<p:commandButton value="Back"
actionListener="#{navBean.back}" update=":content" />
</h:form>
</ui:composition>
回答by jjcapa
Up to now I had the same problem you mention and your post gave me the clue to resolve it. I intended to do exactly what you're trying to do so I hope my solution can help you.
到目前为止,我遇到了你提到的同样问题,你的帖子给了我解决它的线索。我打算做你想做的事情,所以我希望我的解决方案可以帮助你。
My index page, that contains the menu and the container in which the content is updated:
我的索引页,包含菜单和更新内容的容器:
<ui:composition template="./../resources/templates/template.xhtml">
<ui:define name="content">
<h:form>
<h:panelGroup layout="block" styleClass="menu">
<ui:include src="./../resources/templates/menu.xhtml"/>
</h:panelGroup>
<h:panelGroup layout="block" id="content">
<h:panelGroup layout="block" styleClass="content" rendered="#{menuBacking.albums}">
<ui:include src="albums.xhtml"/>
</h:panelGroup>
<h:panelGroup layout="block" styleClass="content" rendered="#{menuBacking.band}">
<ui:include src="band.xhtml"/>
</h:panelGroup>
<h:panelGroup layout="block" styleClass="content" rendered="#{menuBacking.concerts}">
<ui:include src="concerts.xhtml"/>
</h:panelGroup>
<h:panelGroup layout="block" styleClass="content" rendered="#{menuBacking.contacts}">
<ui:include src="contacts.xhtml"/>
</h:panelGroup>
</h:panelGroup>
</h:form>
</ui:define>
</ui:composition>
The menu included in the first panelGroup:
第一个 panelGroup 中包含的菜单:
<p:menu>
<p:menuitem value="Albums" action="#{menuBacking.active}" update="content">
<f:setPropertyActionListener value="albums" target="#{menuBacking.selection}"/>
</p:menuitem>
<p:menuitem value="Band" action="#{menuBacking.active}" update="content">
<f:setPropertyActionListener value="band" target="#{menuBacking.selection}"/>
</p:menuitem>
<p:menuitem value="Concerts" action="#{menuBacking.active}" update="content">
<f:setPropertyActionListener value="concerts" target="#{menuBacking.selection}"/>
</p:menuitem>
<p:menuitem value="Contacts" action="#{menuBacking.active}" update="content">
<f:setPropertyActionListener value="contacts" target="#{menuBacking.selection}"/>
</p:menuitem>
</p:menu>
This is one of the pages I want to display into the content area (just for test purpose):
这是我想显示到内容区域的页面之一(仅用于测试目的):
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
Contacts
</body>
And finally, the bean:
最后,豆:
@ManagedBean
@SessionScoped
public class MenuBacking implements Serializable {
private String selection;
private boolean albums;
private boolean band;
private boolean concerts;
private boolean contacts;
public MenuBacking() {
albums = false;
band = true; // You can define the default page that will be show
concerts = false;
contacts = false;
}
// getters & setters
public void active() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException {
setAlbums(selection.equals("albums"));
setBand(selection.equals("band"));
setConcerts(selection.equals("concerts"));
setContacts(selection.equals("contacts"));
}
}
Be aware the difference between action and actionListener. Action first assigns the value to the property and then execute the method, while actionListener execute the method and then assigns the value.
请注意 action 和 actionListener 之间的区别。Action先给属性赋值再执行方法,而actionListener先执行方法再赋值。
回答by Roger
I made this by using a view path from a bean for including it directly. This is very simple:
我通过使用来自 bean 的视图路径直接包含它来实现这一点。这很简单:
<ui:composition
template="/WEB-INF/includes/templates/page-template.jspx"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jstl/core">
<ui:define name="page-content">
<ui:include src="#{navigation.selectedIncludePath}" />
</ui:define>
</ui:composition>
Then, everytime when the property 'selectedIncludePath' on my navigation bean changes (triggered by ActionEventListeners), the view part named 'page-content' gets updated.
然后,每当我的导航 bean 上的属性“selectedIncludePath”发生变化(由 ActionEventListeners 触发)时,名为“page-content”的视图部分就会更新。
To be clear, the string property 'selectedIncludePath' is filled with filenames to xhtml files.
需要明确的是,字符串属性 'selectedIncludePath' 填充了 xhtml 文件的文件名。
selectedIncludePath = "/WEB-INF/includes/info/about.xhtml";
Of course, this can be updated throu EL from inside a view as well.
当然,这也可以从视图内部通过 EL 进行更新。