2013-01-25 14 views
6

Sto cercando di creare una semplice pagina di visualizzazione delle notizie personalizzabile nella mia applicazione Web, ad esempio Google's one ma molto più semplice, con i frame. Ogni oggetto frame ha semplicemente il titolo e un URL da aggiungere come contenuto.Primefaces per la visualizzazione di più pannelli di contenuto dinamico

Sto usando JSF e primefaces, entrambi sulle versioni più recenti. Quindi il mio backing bean, che è @ViewScoped, ha accesso all'utente registrato, che è memorizzato in un bean @SessionScoped e che l'utente ha caricato i suoi frame corrispondenti.

Il problema si verifica quando si tenta di eseguire l'iterazione sul bean @ViewScoped, perché l'unico modo in cui trovo di farlo è con un tag c:forEach. Questo è il mio modo di fare:

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

che iterazione obviusly non funziona con navegableHomeManager di fagioli perché è @ViewScoped. Quindi il bean verrà ricostruito in ciascuna delle iterazioni. La soluzione che ho raggiunto utilizza un altro bean @SessionScoped tra navegableHomeManager e loggedBean, quindi in questo modo i frame sono memorizzati lì e posso avere accesso ad essi correttamente nell'iterazione. Funziona con il codice sopra.

Tuttavia, non credo che sia obbligatorio utilizzare un bean @SessionScoped (creando un bean specifico per ogni singolo caso) ogni volta che si desidera eseguire l'iterazione in questo modo. Ecco perché ho provato a utilizzare i componenti per evitare l'iterazione.

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

Non funziona né quando il fagiolo è @ViewScoped o @SessionScoped, perché anche le proprietà di cornici sono impostate, il tag ui:include è già stato costruito senza alcun percorso di destinazione, quindi non può rendere la destinazione percorso dinamicamente. Penso che, poiché ui:include viene applicato contemporaneamente a c:forEach, l'utilizzo di un tag c:forEach è davvero l'unico modo per procedere.

Raggruppa le tue idee.

UPDATE

Qui ho posto più xhtml codice per aiutare nella comprensione del contesto. La pagina del nuovo è integrata in un modello. Questa è la pagina che si rivolge (/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> 

E questo è il modo in cui ho anche provato a farlo, ma non fare il tag c:forEach a lavorare:

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

E questo è l'intestazione supporto di fagioli:

@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 

risposta

6

Stick a <c:forEach>. Fa il lavoro che stai cercando. Il <ui:include> viene eseguito durante la fase di creazione della vista, pertanto il tag di iterazione deve essere eseguito anche durante la fase di creazione della vista.

Per quanto riguarda il problema @ViewScoped fagioli, hai 2 opzioni:

  1. spegnere parziale stato il risparmio per la vista particolare:

    <context-param> 
        <param-name>javax.faces.FULL_STATE_SAVING_VIEW_IDS</param-name> 
        <param-value>/news.xhtml</param-value> 
    </context-param> 
    
  2. cambiarlo in un @RequestScoped di fagioli e l'uso <f:param> e @ManagedProperty per mantenere lo stato tra i postback in base ai parametri della richiesta.

Ci sarebbe una terza opzione se JSF 2.2 è disponibile: basta eseguire l'aggiornamento a JSF 2.2. Hanno risolto il problema dell'uovo di gallina in vista dei fagioli con scope e del salvataggio parziale dello stato.

+0

Grazie per la risposta. Per qualche ragione, la soluzione basata su 'context-param' non funziona. 'navegableHomeManager' sta recuperando i frame direttamente dal' loggedBean', ma il tag 'forEach' non sta eseguendo l'iterazione nemmeno' # {fn: length (navegableHomeManager._UserFrames)} 'restituisce' 1'. Il bean viene creato solo quando accedo alla pagina, che è corretta. Inoltre, non posso eseguire l'aggiornamento a JSF 2.2 poiché non ci sono versioni stabili e non posso fidarmi di esso al 100%. –

+0

Per quanto riguarda il parametro contesto, apparentemente hai specificato l'ID vista errato (nota: un ID vista non è un URL, è il percorso relativo al contesto del file fisico, quindi anche se hai mappato la tua cosa JSF su '* .jsf', dovresti comunque usare '.xhtml' nell'ID vista). Per quanto riguarda il resto, mi dispiace è difficile capire il problema sulla base delle informazioni fornite finora. – BalusC

+0

Ho aggiornato la domanda aggiungendo altro del mio codice BalusC. Spero che ti sarà d'aiuto. –

Problemi correlati