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

发布于 2024-11-03 19:40:44 字数 3450 浏览 0 评论 0原文

我正在尝试创建一个 Facelet 页面,该页面通过 ajax 调用更新 元素。每当单击 时,应该发生 ajax 调用,并且只有 Facelet 模板的 部分应该发生被更新。我的问题与此处中的问题完全相同,但解决方案结束那里不起作用。此外,考虑到评论,答案是否被接受是相当模糊的。我陷入困境,没有任何解决方案,不确定这是否与

我有的 PrimeFaces FAQ#4 有关另一个带有 的解决方案提案,但不太确定这是否是一个好的解决方案。我将活动页面存储在 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>

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

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:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

べ映画 2024-11-10 19:40:44

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

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

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

最后, 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"));
    }
}

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

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:

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

不必了 2024-11-10 19:40:44

我通过使用 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 从视图内部更新。

I made this by using a view path from a bean for including it directly. This is very simple:

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

To be clear, the string property 'selectedIncludePath' is filled with filenames to xhtml files.

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

Of course, this can be updated throu EL from inside a view as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文