2016-06-03 5 views
6

Ho un:Come eseguire il rendering di un componente JSF solo se sono rappresentati almeno due figli (titolo + oggetto)?

<h:panelGroup /> 
    <h:outputText value="title" /> 
    <h:itemThatSometimesWillShow rended="sometimes1" /> 
    <h:itemThatSometimesWillShow rended="sometimes2" /> 
    <h:itemThatSometimesWillShow rended="sometimes3" /> 
    ...many more 

E vorrei che, se nessuno degli spettacoli itemThatSometimesWillShow, l'intero pannello (il titolo, in realtà) non mostra neanche.

Ho provato con componente composito #{cc.childCount} > 1, ma non sono all'interno di un'implementazione composita, quindi sembra che restituirà sempre 0.

Qualche idea? (che sto cercando qualcosa con js o EL da utilizzare in rendered attributo della panelGroup genitore)

risposta

2

vorrei brevemente andare con questo:

<h:panelGroup rendered="{bean.isSometimes()}"/> 
    <h:outputText value="title" /> 
    <h:itemThatSometimesWillShow rended="{bean.isSometimes1()}" /> 
    <h:itemThatSometimesWillShow rended="{bean.isSometimes2()}" /> 
    <h:itemThatSometimesWillShow rended="{bean.isSometimes3()}" /> 

e il fagiolo:

public boolean isSometimes() 
{ 
    return isSometimes1() || isSometimes2() || isSometimes3(); 
} 
+1

Questo è quello che ho fatto per ora, grazie! Ma non c'è un modo più astratto? –

+0

Posso solo pensare a ciò che BalusC ha scritto qui. :) –

4

Ciò è possibile con l'API di flusso EL 3.0. Il mio primo tentativo è stato:

Tuttavia, questo non ha funzionato abbastanza bene. Inaspettatamente si è imbattuto in un ciclo infinito che alla fine si è concluso con un OutOfMemoryError. Sembra che la variabile #{component} EL rappresenti ancora il componente precedente nel momento in cui viene consultato l'attributo rendered. Si tratta di un problema di uova di gallina: lo #{component} per il componente corrente viene iniettato solo se l'attributo rendered valuta true.

Dato che, posso vedere altre due opzioni: in modo esplicito trovare il componente ID come sotto,

<h:panelGroup id="foo" rendered="#{component.findComponent('foo').children.stream().filter(c -> c.rendered).count() gt 1}"> 
    <h:outputText value="title" /> 
    <h:panelGroup rendered="#{false}">item1</h:panelGroup> 
    <h:panelGroup rendered="#{false}">item2</h:panelGroup> 
    <h:panelGroup rendered="#{false}">item3</h:panelGroup> 
</h:panelGroup> 

o lasciarlo stampare qualche classe CSS che a sua volta fa un display:none;.

<h:panelGroup styleClass="#{component.children.stream().filter(c -> c.rendered).count() gt 1 ? 'show' : 'hide'}"> 
    <h:outputText value="title" /> 
    <h:panelGroup rendered="#{false}">item1</h:panelGroup> 
    <h:panelGroup rendered="#{false}">item2</h:panelGroup> 
    <h:panelGroup rendered="#{false}">item3</h:panelGroup> 
</h:panelGroup> 
+1

Grande! Sto pensando: non c'è un metodo come 'componente.children.size()'? Lo cercherò ... –

+1

Sì, esattamente così, o "# {component.childCount}" per una maggiore efficacia. Non è utile solo per risolvere il tuo problema specifico in quanto non consulta l'attributo 'rendered' dei bambini. – BalusC

Problemi correlati