2013-01-25 59 views
6

我正在嘗試在我的web應用程序中執行一種簡單的可自定義的新聞查看頁面,如Google's one,但要簡單得多,並帶有框架。每個框架對象都只有他的標題和一個URL作爲其內容添加。Primefaces要顯示多個動態內容面板

我在使用JSF和primefaces,都在他們的最新版本。因此,我的支持bean(@ViewScoped)可以訪問記錄的用戶,該用戶存儲在@SessionScoped bean中,並且該用戶已加載了相應的框架。

問題出現在我試圖在@ViewScoped bean上迭代它時,因爲唯一的辦法就是使用c:forEach標籤。這就是我的方式:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
xmlns:ui="http://java.sun.com/jsf/facelets" 
xmlns:f="http://java.sun.com/jsf/core" 
xmlns:h="http://java.sun.com/jsf/html" 
xmlns:c="http://java.sun.com/jsp/jstl/core" 
xmlns:p="http://primefaces.org/ui" 
xmlns:fn="http://java.sun.com/jsp/jstl/functions"> 
<h:form> 
    <p:panel header="Noticias"> 
     <h:panelGrid columns="#{fn:length(navegableHomeManager._UserFrames)}" 
      width="100%"> 
      <c:forEach var="frame" items="#{navegableHomeManager._UserFrames}"> 
       <p:column> 
        <p:panel header="#{frame._Name}" closable="true" 
         style="width:95%;height:500px;" id="#{frame._Name}"> 
         <p:ajax event="close" 
          listener="#{navegableHomeManager.actionFrameClosed}" /> 
         <ui:include src="#{frame._Path}" /> 
        </p:panel> 
       </p:column> 
      </c:forEach> 
     </h:panelGrid> 
    </p:panel> 
</h:form> 

該迭代obviusly,因爲它是@ViewScopednavegableHomeManager豆工作。所以這個bean將在每次迭代中重建。我已經達到的解決方案在navegableHomeManagerloggedBean之間使用另一個@SessionScoped bean,這樣就可以將幀存儲在那裏,並且我可以在迭代中正確訪問它們。這與上面的代碼一起工作。

但是我不認爲應該強制使用一個@SessionScoped bean(爲每個案例創建一個特定的bean),每次我想以這種方式迭代時。 這就是爲什麼我嘗試使用組件來避免迭代。

<p:dataGrid columns="#{fn:length(navegableHomeManager._UserFrames)}" 
      value="#{navegableHomeManager._UserFrames}" var="frame"> 
    <p:column> 
     <p:panel header="#{frame._Name}" closable="true" 
        style="width:95%;height:500px;"> 
      <p:ajax event="close" 
         listener="#{navegableHomeManager.actionFrameClosed}" /> 
      <ui:include src="#{frame._Path}" /> 
     </p:panel> 
    </p:column> 
</p:dataGrid> 

它不工作,既不當bean是@ViewScoped@SessionScoped,因爲即使是幀屬性設置中,ui:include標籤已經建成,沒有目的地的路徑,所以我不能渲染目標小徑路徑。我認爲,因爲ui:include正在與c:forEach同時應用,所以使用c:forEach標記是真正實現此目的的唯一方法。

彙集您的想法。

UPDATE

我在這裏發佈更多XHTML代碼在上下文的理解提供幫助。新的頁面已集成到模板中。這是這是針對該頁面(/system/home/index.xhtml):

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
template="/templates/general_template.xhtml" 
xmlns:ui="http://java.sun.com/jsf/facelets" 
xmlns:f="http://java.sun.com/jsf/core" 
xmlns:c="http://java.sun.com/jsp/jstl/core"> 

<ui:define name="metadata"> 
    <f:event type="preRenderView" 
     listener="#{navegableHomeManager.initialize}" /> 
</ui:define> 

<ui:define name="general_content"> 
    <ui:include src="/system/home/home_view.xhtml" /> 
</ui:define> 

這就是我也試圖做到這一點,但不能使c:forEach標籤的工作:

<context-param> 
    <param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name> 
    <param-value>/system/home/index.xhtml</param-value> 
</context-param> 

這就是支持bean頭:

@ManagedBean 
@ViewScoped 
@URLMapping(id = "home", pattern = "/home", viewId = "/system/home/index.xhtml") 
public class NavegableHomeManager extends SystemNavegable { 

/** 
* 
*/ 
private static final long serialVersionUID = 6239319842919211716L; 

@ManagedProperty(value = "#{loggedBean}") 
private LoggedBean _LoggedBean; 

//More stuff 

回答

6

堅持<c:forEach>。它做你正在尋找的工作。 <ui:include>在視圖構建時運行,因此迭代標記也應在視圖構建時運行。

至於@ViewScoped豆問題,你已經2種選擇:

  1. 關閉部分保存狀態的特定視圖:

    <context-param> 
        <param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name> 
        <param-value>/news.xhtml</param-value> 
    </context-param> 
    
  2. 將其更改爲@RequestScoped豆和使用<f:param>@ManagedProperty可通過請求參數在回發期間維護狀態。

如果JSF 2.2可用,將會有第三個選項:只需升級到JSF 2.2。他們已經解決了視圖範圍的豆類和部分狀態保存中的雞蛋問題。

+0

感謝您的回答。出於某種原因,基於'context-param'的解決方案不起作用。 'navegableHomeManager'現在正在從'loggedBean'直接恢復幀,但'forEach'標籤並沒有進行迭代,即使'#{fn:length(navegableHomeManager._UserFrames)}'返回'1'。只有當我訪問該頁面時才建立bean,這是正確的。我也無法升級到JSF 2.2,因爲沒有穩定版本,我不能相信它100%。 –

+0

至於上下文參數,顯然你指定了錯誤的視圖ID(注意:視圖ID不是一個URL,它是與物理文件相關的上下文路徑,所以即使你將JSF映射到'* .jsf'上,你仍然應該在視圖ID中使用'.xhtml')。關於剩餘,對不起,根據目前提供的信息很難理解問題。 – BalusC

+0

我已經更新了添加更多我的代碼BalusC的問題。希望它會有所幫助。 –