【问题标题】:Partial rendering JSF components部分渲染 JSF 组件
【发布时间】:2011-09-03 06:44:34
【问题描述】:

通过包含不同的源文件(带有面板和组件)来讨论如何部分渲染(div)。取决于菜单操作。如果正确理解 JSF 阶段,View 将在最后一个阶段 Render Response 期间重建。如果我有事件和动作,它们将在 Invoke Application 阶段(之前的阶段)被调用。

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

在调用 ui:include 之前,我应该如何处理菜单 action(设置包含页面)?

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

ma​​sterLayout.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>
..

【问题讨论】:

  • 实际上,ui:include 标记是为页面上的其他 ajax 操作(不是菜单操作)调用的,我没有显式呈现“内容”div。

标签: java jsf richfaces


【解决方案1】:

您还必须有一个模板页面,因为您在 layoutClient.xhtml 中定义 topcontent 所以我认为您试图对 @987654322 过于笼统@page,因为它似乎也可以用作模板。假设您的模板页面名为template.xhtml。您逃避的标准模式是使您的模板页面如下所示:

模板.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 标签!

【讨论】:

  • 感谢重播。我确实有一个名为 masterLayout.xhtml(上图)的模板文件,但忘记包含它。也许我会尝试努力将内容动态加载到同一页面中。但是根据您的解决方案,我猜整个页面都必须刷新?
  • 是的,没错。为更清洁、更易于维护的代码 (IMO) 付出的代价很小。此外,如果您始终在页面中使用 AJAX,则后退按钮将按预期工作。如果您使用 AJAX 导航,则不会记录在页面历史记录中,因此按返回会将用户带到 layoutClient.xhtml 之前的最后一页。
猜你喜欢
  • 2012-01-17
  • 1970-01-01
  • 1970-01-01
  • 2011-02-06
  • 2011-07-07
  • 2011-12-12
  • 1970-01-01
  • 2013-08-31
  • 2010-12-14
相关资源
最近更新 更多