Частичная визуализация компонентов JSF - PullRequest
3 голосов
/ 27 мая 2011

О том, как выполнить частичный рендеринг (div), включая различные исходные файлы (с панелями и компонентами). В зависимости от действий меню. Если правильно понять фазы JSF, View перестраивается во время Render Response , последней фазы. И если у меня есть события и действия, они будут вызваны во время фазы Invoke Application , перед предыдущей.

Все, что я хочу сделать, это установить включающую страницу xhtml для определенной команды меню через ajax, прежде чем представление будет перерисовано. Но ui: include всегда вызывается перед действием меню. Я пробовал использовать richfaces 4 (a4j: param, rich: panel и т. Д.) И стандартные компоненты JSF 2.0 (f: param, h: panelGroup), но ui: include всегда вызывается до действие.

Что я должен сделать, чтобы обработать меню action (чтобы установить страницу включения), прежде чем будет вызван ui: include ?

PS. Это должен быть стандартный шаблон вместо статического содержимого. Но я нашел очень мало примеров по этому поводу в сети?!

Menu.xhtml

<rich:toolbar itemSeparator="line">
...
<rich:dropDownMenu mode="ajax">

    <f:facet name="label">
                <h:panelGroup>
                    <h:outputText value="Menu 1" />
                </h:panelGroup>
            </f:facet>
            <rich:menuItem id="newActivityMenu" action="#{navigationBean.menuAction}" render="content" label="New">
                <a4j:param id="newActivityParam" name="includeContentPage" value="/user/Create.xhtml" />
            </rich:menuItem>
...

NavigationBean.Java

    @ManagedBean
@RequestScoped
public class NavigationBean {

    public String menuAction() {
    String param = JsfUtil.getRequestParameter("includeContentPage");
    this.includedContentPage = param;
    JsfUtil.log(this, "Including Content Page : " +param);

    FacesContext.getCurrentInstance().renderResponse();
    return "";
}

public String getIncludedContentPage() {
    if(includedContentPage == null)
        return "";
    else if(!includedContentPage.endsWith(".xhtml"))
        includedContentPage += ".xhtml";
    JsfUtil.log(this, "Get Content Page : " +includedContentPage);
    return includedContentPage;
    }

layoutClient.xhtml

...
<ui:define name="top">
        <ui:include src="/resources/viewComponents/menuTop.xhtml"/>
    </ui:define>
    <ui:define name="content">                
        <ui:include src="#{navigationBean.includedContentPage}"/>
    </ui:define>
...

masterLayout.xhtml (добавлено)

...
<h:body>
    <div id="top" >
        <ui:insert name="top">Top Default</ui:insert>
    </div>
    <div id="left">
        <ui:insert name="left">Left Default</ui:insert>
    </div>
         <ui:insert name="content">Content Default</ui:insert>
    </h:body>
..

1 Ответ

2 голосов
/ 27 мая 2011

У вас также должна быть страница шаблона, так как вы определяете top и content в layoutClient.xhtml, поэтому я думаю, что вы пытаетесь быть слишком общим со страницей layoutClient.xhtml как представляется, функционирует как шаблон. Предположим, что ваша страница шаблона называется template.xhtml. Стандартный шаблон, к которому вы обратились, должен сделать вашу страницу шаблона примерно такой:

template.xhtml

...
<ui:insert name="top">
    <ui:include src="/resources/viewComponents/menuTop.xhtml"/>
</ui:insert>
...
<ui:insert name="content" />
...

Это означает, что все ваши страницы содержат меню в верхней части (по умолчанию они могут переопределить это) и что они должны указывать свое собственное содержимое, что имеет смысл.

Теперь, вместо того, чтобы пытаться создать страницу наподобие layoutClient.xhtml, которая делает хитрые вещи, чтобы определить, какой контент вставлен, создайте каждую страницу отдельно так:

page1.xhtml

<ui:composition template="template.xhtml">
    ...
    <ui:define name="content">
        <p>This is a page that defines some content and also includes my menu that it inherits from template.xhtml</p>
    </ui:define>
    ...
</ui:composition>

page2.xhtml

<ui:composition template="template.xhtml">
    ...
    <ui:define name="content">
        <p>This is another page that defines some content and also includes my menu that it inherits from template.xhtml</p>
    </ui:define>
    ...
</ui:composition>

Обе эти страницы наследуют ваше меню и размещают содержимое в соответствующем месте.

При такой конфигурации все, что требуется от вашего menuAction() метода - это вернуть ссылку на page1.xhtml или page2.xhtml. Кроме того, вам не требуется сложное использование параметров или ручные вызовы тегов renderResponse() или a4j:param!

...