Частичный рендеринг страниц с Primefaces - навигация JSF 2.0 - PullRequest
2 голосов
/ 27 апреля 2011

Я пытаюсь создать страницу лицевой страницы, которая обновляет элементы <ui:insert> с помощью вызовов ajax.При каждом нажатии <p:commandButton action="next"/> должен выполняться вызов ajax, и только <ui:insert> части шаблона лицевой стороны должны быть обновлены.Мой вопрос точно такой же, как вопрос в здесь , но решение там не работает.Кроме того, учитывая комментарий, весьма неоднозначно, принят ответ или нет.Я застрял без какого-либо решения и не уверен, связано ли это с 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 ]

3 голосов
/ 28 апреля 2011

До сих пор у меня была та же проблема, о которой вы упоминали, и ваше сообщение дало мне ключ к ее решению.Я намеревался сделать именно то, что вы пытаетесь сделать, поэтому я надеюсь, что мое решение может помочь вам.

Моя страница указателя, которая содержит меню и контейнер, в котором обновляется содержимое:

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

Меню, входящее в первую группу панелей:

<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.Действие сначала назначает значение свойству, а затем выполняет метод, в то время как actionListener выполняет метод, а затем назначает значение.

1 голос
/ 19 марта 2013

Я сделал это, используя путь представления от бина для непосредственного включения. Это очень просто:

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

Затем, каждый раз, когда изменяется свойство selectedIncludePath в моем компоненте навигации (запускаемое ActionEventListeners), обновляется часть представления с именем page-content.

Для ясности, строковое свойство selectedIncludePath заполняется именами файлов в файлах xhtml.

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

Конечно, это может быть обновлено через EL также изнутри вида.

...