使用Primefaces进行部分页面渲染 - JSF 2.0导航

时间:2011-04-27 16:27:26

标签: java java-ee jsf-2 facelets primefaces

我正在尝试创建一个使用ajax调用更新<ui:insert>元素的facelet页面。每当点击<p:commandButton action="next"/>时,都应进行ajax调用,并且只应更新facelet模板的<ui:insert>个部分。我的问题与here中的问题完全相同,但那里的解决方案不起作用。此外,考虑到评论,如果答案被接受,则是非常模糊的。我没有任何解决方案,但不确定这是否与PrimeFaces FAQ#4

相关

我有<ui:import>的另一个解决方案提案,但不太确定这是否是一个很好的解决方案。我将活动页面存储在bean属性中并使用ajax调用更新值。所以任何评论和/或想法都不仅仅是值得赞赏的。 这是我的建议:

的template.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 &amp; 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

@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

<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

<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>

2 个答案:

答案 0 :(得分:3)

到目前为止,我提到了同样的问题,你的帖子给了我解决问题的线索。我打算做你正在尝试的事情,所以我希望我的解决方案可以帮助你。

我的索引页面,其中包含菜单和更新内容的容器:

<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>

第一个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>

这是我要在内容区域中显示的页面之一(仅用于测试目的):

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets">

<body>
    Contacts
</body>

最后,豆子:

@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"));
    }
}

请注意action和actionListener之间的区别。 Action首先将值赋给属性然后执行该方法,而actionListener执行该方法然后赋值。

答案 1 :(得分:1)

我是通过使用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>

然后,每当我的导航bean上的属性“selectedIncludePath”发生更改(由ActionEventListeners触发)时,名为“page-content”的视图部分都会更新。

要清楚,字符串属性'selectedIncludePath'用文件名填充到xhtml文件。

selectedIncludePath = "/WEB-INF/includes/info/about.xhtml";

当然,这也可以通过EL从视图内部进行更新。