2016-06-03 12 views
6

mam:Jak renderować komponent JSF tylko wtedy, gdy renderowane są co najmniej dwoje dzieci (tytuł i element)?

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

I chciałbym, że jeżeli żaden z itemThatSometimesWillShow pokazach, cały panel (tytuł, faktycznie) nie pokazuje albo.

Próbowałem z komponentem komponentu #{cc.childCount} > 1, ale nie jestem wewnątrz złożonej implementacji, więc wygląda na to, że zawsze zwróci 0.

Każdy pomysł? (szukam czegoś z js lub EL do wykorzystania w rendered atrybut panelGroup dominującej)

Odpowiedz

2

chciałbym krótko iść z tym:

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

aw Fasola:

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

To, co zrobiłem na razie, dzięki! Ale czy nie ma bardziej abstrakcyjnego sposobu? –

+0

Mogę tylko pomyśleć o tym, co BalusC napisał już tutaj. :) –

4

Można to osiągnąć za pomocą API strumienia EL 3.0. Moja pierwsza próba to:

<h:panelGroup rendered="#{component.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> 

Jednak to nie działało całkiem dobrze. Niespodziewanie natrafił na nieskończoną pętlę, która ostatecznie zakończyła się OutOfMemoryError. Wygląda na to, że zmienna EL nadal zawiera poprzedni komponent w momencie skonsultowania atrybutu rendered. To jest trochę problemu z jajkiem kurzego: #{component} dla bieżącego komponentu jest wstrzykiwany tylko wtedy, gdy jego atrybut rendered ocenia true.

Biorąc pod uwagę, że widzę jeszcze dwie opcje: wyraźnie odnaleźć komponentu przez ID poniżej,

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

albo niech wydrukować niektóre klasy CSS, która z kolei działa 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

Świetnie! Myślę: czy nie istnieje metoda typu "component.children.size()"? Będę go szukać ... –

+1

Tak, dokładnie to lub '# {component.childCount}' dla większej efektywności. Nie jest to pomocne przy rozwiązywaniu określonego problemu, ponieważ nie sprawdza się z atrybutem "wyrenderowany" dla dzieci. – BalusC

Powiązane problemy