部分呈现JSF组件

时间:2011-05-27 09:52:35

标签: java jsf richfaces

通过包含不同的源文件(使用面板和组件)来讨论如何部分渲染(div)。取决于菜单操作。如果正确理解了JSF阶段,则在渲染响应(最后阶段)期间重建视图。如果我有事件和操作,它们将在调用应用程序阶段(之前的阶段)中调用。

我想要做的就是在重新渲染View之前,通过ajax为特定菜单命令设置包含xhtml页面。但是在菜单操作之前始终会调用 ui:include 。我尝试过使用richfaces 4(a4j:param,rich:panel等)和标准JSF 2.0(f:param,h:panelGroup)组件,但 ui:include 总是先调用行动。

在调用 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 个答案:

答案 0 :(得分:2)

您必须拥有一个模板页面,因为您在layoutClient.xhtml中定义了 top 内容,所以我认为您正试图过于笼统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.xhtmlpage2.xhtml的链接。此外,您无需复杂使用参数或手动调用renderResponse()a4j:param标记!