【问题标题】:how to do partial page rendering (center content) with jsf2 templating via ajax (from menu)如何通过ajax(来自菜单)使用jsf2模板进行部分页面渲染(中心内容)
【发布时间】:2011-10-12 20:35:16
【问题描述】:

我一直在努力让它工作 2 周,我正在尝试将来自 BalusC 的信息从这 2 个帖子合并到 (link1link2) 以通过菜单实现中心内容区域的部分页面呈现左边。因此,左侧的链接将通过使用<f:ajax> 或可能通过richfaces 的<a4j:ajax> 部分页面呈现来更新中心内容

-------------------------------------------------- ---- |包括1 个链接 | | | include2 链接 |中心内容,如 include1.xhtml | | include3 链接 | | -------------------------------------------------- ----

我的 page-layout.xhtml(include1.xhtml、include2.xhtml、..使用的主模板)看起来像这样。

<h:body>
    <div id="top" class="top">
        <ui:insert name="top">page-layout default top content</ui:insert>
    </div>
    <div>
        <div id="left">
            <h:form id="navigationFormId">             
                    <f:ajax render=":contentForm">                                        
                        <h:commandLink value="include1" 
                                       action="#{navigationBean.setPage('include1')}" />
                        <p></p>
                        <h:commandLink value="include2" 
                                       action="#{navigationBean.setPage('include2')}" />                    
                        <p></p>
                        <h:commandLink value="include3" 
                                       action="#{navigationBean.setPage('include3')}" />   
                        <p></p>
                    </f:ajax>                                     
            </h:form>
        </div>
        <div id="content">
           <ui:insert name="content">

                <h:panelGroup id="contentPanelGroup" layout="block"> 
                    <h:form id="contentForm">

                        <h:panelGroup rendered="#{navigationBean.page == 'include1'}">            
                            <ui:include src="include1.xhtml" />         
                        </h:panelGroup> 
                        <h:panelGroup rendered="#{navigationBean.page == 'include2'}">            
                            <ui:include src="include2.xhtml" />         
                        </h:panelGroup>
                        <h:panelGroup rendered="#{navigationBean.page == 'include3'}">             
                            <ui:include src="include3.xhtml" />         
                        </h:panelGroup>

                    </h:form> 
               </h:panelGroup>     

            </ui:insert>
        </div>
    </div>
</h:body>

NavigationBean.java 通过带有@Named 的 CDI 定义为 ViewScoped bean

公共类 NavigationBean 实现可序列化 {

public NavigationBean() {}

public String getPage() {return page;}
public void setPage(String p) {page = p;}
private String page = "include1";

}

包含的页面是include1.xhtml和include2.xhtml之类的文件,点击左侧菜单链接时应该加载到中心内容,这里是一个示例include2.xhtml

<h:body>

    <ui:composition template="page-template.xhtml">
        <ui:define name="content">

             include2

             <h:form> 
                 form components for include2
             </h:form>

        </ui:define>
    </ui:composition>

</h:body>

我得到 FileNotFoundException,虽然堆栈跟踪没有 告诉哪个,但删除

<h:panelGroup rendered=".....>
    <ui:include src="..." />
</h:panelGroup>

tags 删除异常。我认为这是基于 2 篇 BalusC 帖子完成此任务的正确实现,但无法使其正常工作。

【问题讨论】:

  • 您的模板方法令人困惑且不明智。我的印象是你误解了this answer的最后一段。我并不是说你应该混合使用这两种方法。我的意思是你应该使用一个 或 另一个。我建议还原更改,以便您最终得到与答案中所示相同的示例(或者忘记 ajax 加载并使用普通链接的纯主模板方法)。
  • 是的 BalusC,这正是我从你在帖子的最后一段中想到的,它没有说使用一个或另一个,所以我认为我可以使用这种方法的模板。所以让我问这个。通过 facelets 模板渲染部分页面是否容易完成。我看到richfaces 展示和icefaces 展示这样做,但primefaces 在单击左侧链接时会刷新整个页面。顺便提一句。如果想法是结合模板和你建议的方式来做 ppr 是明智的 :-)
  • 你可以组合它们,但不能这样。 &lt;ui:insert name="content"&gt; 在一个不明智的地方。此外,我认为您的意思是使用 template="page-layout.xhtml" 而不是 template="page-template.xhtml" (并不是说这会像您期望的那样工作,但这至少是 FNFE 的原因)。
  • BalusC,你说得对,谢谢指正。我在帖子中有错字。 IncludedX.xhtml 应该引用模板名称 page-layout.xhtml。你能给我举个例子,说明如何将它们结合起来,用菜单/内容设计完成部分页面渲染的 faeclets 版本。我真的很挣扎如何做到这一点,并愿意阅读和调查,只是找不到一个简洁地展示如何做的地方。顺便说一句,感谢您花时间回复,我很感激并阅读了你们中的许多博客和帖子

标签: ajax templates jsf render partial


【解决方案1】:

您收到的错误表明找不到包含...xhtml 页面。文件位于何处?它们应该与 page-layout.xhtml 文件位于同一目录中吗?为了简化我只是测试包含是否有效的所有内容,你可以替换它:

<h:form id="contentForm">
        <h:panelGroup rendered="#{navigationBean.page == 'include1'}">            
                <ui:include src="include1.xhtml" />         
        </h:panelGroup> 
        <h:panelGroup rendered="#{navigationBean.page == 'include2'}">            
                <ui:include src="include2.xhtml" />         
        </h:panelGroup>
        <h:panelGroup rendered="#{navigationBean.page == 'include3'}">             
                <ui:include src="include3.xhtml" />         
        </h:panelGroup>
</h:form> 

与:

<h:form id="contentForm">
        <ui:include src="include1.xhtml" />         
</h:form>

【讨论】:

  • 感谢 ross,好建议,我已经尝试过了,只是盲目地包含其中一个以尝试使其工作。所有文件都直接在根目录中,所以路径问题应该不是问题,我相信它与 JSF 有更多关系。如果我只是打印出导航 bean 的值,"#{navigationBean.page} 当然我也不例外,它确实告诉我它正在尝试包含 includeX.xhtml,只是 &lt;ui:include src="include1.xhtml" /&gt; 不起作用:-(
  • ross,BalusC 指出我的 includeX.xhtml 文件中有错字,因此已修复,感谢您的回复,仍在等待是否有人可以告诉我如何进行 facelets 部分页面渲染,如果我想出一个解决方案,将发布一个解决方案。
  • 我想提醒那些尝试实现它的人,这有点棘手,我不得不做一些代码更改,但基本想法正确,你必须更新一个 而不仅仅是一个
    ,下面会贴一个例子
【解决方案2】:

我能够通过 JSF2/Ajax 和 richfaces4 获得设计(我假设其他实现也可以),其中通过模板实现的左侧导航菜单项能够通过 ajax 呈现模板的中心内容,防止整页刷新,以及它具有的闪烁效果。

我的 navigationmenu.xhtml 代码如下所示

<ui:composition>
<h:form id="navigationFormId">
        <rich:collapsiblePanel id="carrierCollapsibleId" header="Links that update center content" switchType="client">
            <h:commandLink  id="linkId1" action="/page1" value="Update Center Content with page1">
                <a4j:ajax execute="@form" render=":centerContentDiv,:centerForm" />                    
            </h:commandLink>
            <br />
            <h:commandLink  id="linkId2" action="/page2" value="Update Center Content with page2">
                <a4j:ajax execute="@form" render=":centerContentDiv,:centerForm" />                    
            </h:commandLink>
</rich:collapsiblePanel>
...
</h:form>

我相信a4j:ajax 标签的render=":centerContentDiv,:centerForm" 属性可以更改为仅render=":centerForm",但尚未对此进行测试。然而,我知道两者一起工作。此外,我尝试了在 ID 之间使用空格的 JSF2 ajax 标记并得到了错误,所以我去了richfaces 4.x 的 a4j,然后如果没有使用空格,可以使用逗号。

现在,为了使其工作,每个 pageX.xhtml 文件,例如 page1.xhtml 都需要有 &lt;h:form id="centerForm"&gt;,这里是 page1.xhtml 的示例

<ui:composition template="/templates/uiTemplate.xhtml">
        <ui:define name="center_content">                                
            <h:form id="centerForm">
               <!-- put your components in here -->    

            </h:form>
        </ui:define>
    </ui:composition>

一个限制是每个使用模板的视图都必须定义一个&lt;h:form id=centerForm" ...&gt;,否则JSF2 会抱怨它找不到渲染目标。

我的 uiTemplate.xhtml 文件有页眉、页脚的代码,但是定义了导航和中心内容的相关部分如下

<div class="header_content">
        <div id="left">
            <ui:include src="navigationMenu.xhtml" />
        </div>
        <div id="center_content">
                                 <!-- think this panelGroup wrapper can be -->
                                 <!-- removed. need to test that though -->
            <h:panelGroup id="centerContentDiv" layout="block">
                <ui:insert name="center_content" />
            </h:panelGroup>
        </div>
    </div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-23
    • 2011-07-03
    • 2010-12-15
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    相关资源
    最近更新 更多