2013-02-05 10 views
5

Ich habe eine Seite, auf die der Benutzer über Android, iPhone, BlackBerry oder über einen unbekannten Browser zugreifen kann. Ich habe 4 rich:panel s, eine für jede Plattform und die letztere ist eine generische.Wie rende ich eine Komponente nur, wenn eine andere Komponente nicht gerendert wird?

Der Code:

<rich:panel id="dlAndroid" rendered="#{fn:containsIgnoreCase(request.getHeader('User-Agent'), 'Android')}"> 
    ... 
</rich:panel> 

<rich:panel id="dlIphone" rendered="#{fn:containsIgnoreCase(request.getHeader('User-Agent'), 'iPhone')}"> 
    ... 
</rich:panel> 

<rich:panel id="dlBlackberry" rendered="#{fn:containsIgnoreCase(request.getHeader('User-Agent'), 'BlackBerry')}"> 
    ... 
</rich:panel> 

<rich:panel id="dlGeneric" rendered="#{ ---> WHAT TO WRITE HERE? <--- }"> 

Wie kann ich die letzte rich:panel nur, wenn keiner der anderen machen erbracht worden ist?

+1

Haben Sie die hässlichste Lösung ausprobiert? 'gerendert =" # {nicht (fn: containsIgnoreCase (request.getHeader ('Benutzer-Agent'), 'Android') oder fn: containsIgnoreCase (request.getHeader ('User-Agent'), 'iPhone') oder fn: containsIgnoreCase (request.getHeader ('User-Agent'), 'BlackBerry'))} "'? –

+0

@LuiggiMendoza Ich habe etwas ähnliches versucht, aber nicht so, weil ich versuchte, diese Zeilen nicht zu wiederholen. Aber auch wenn es hässlich ist, funktioniert deine Lösung. –

Antwort

3

Auf den Punkt gebracht, Ihre Frage, wie im Titel angegeben kann konkret beantwortet werden wie:

<rich:panel binding="#{panel1}" ...> 
    ... 
</rich:panel> 
<rich:panel binding="#{panel2}" ...> 
    ... 
</rich:panel> 
<rich:panel binding="#{panel3}" ...> 
    ... 
</rich:panel> 
<rich:panel ... rendered="#{not panel1.rendered and not panel2.rendered and not panel3.rendered}"> 
    ... 
</rich:panel> 

Allerdings ist es in diesem speziellen Fall vielleicht schönere jene langatmig Ausdrücke mit <c:set> an alias:

<c:set var="android" value="#{fn:containsIgnoreCase(header['User-Agent'], 'Android')}" scope="request" /> 
<c:set var="iPhone" value="#{fn:containsIgnoreCase(header['User-Agent'], 'iPhone')}" scope="request" /> 
<c:set var="blackBerry" value="#{fn:containsIgnoreCase(header['User-Agent'], 'BlackBerry')}" scope="request" /> 

<rich:panel ... rendered="#{android}"> 
    ... 
</rich:panel> 
<rich:panel ... rendered="#{iPhone}"> 
    ... 
</rich:panel> 
<rich:panel ... rendered="#{blackBerry}"> 
    ... 
</rich:panel> 
<rich:panel ... rendered="#{not android and not iPhone and not blackBerry}"> 
    ... 
</rich:panel> 

Beachten Sie, dass es eine kürzere Möglichkeit gibt, den Anforderungsheader durch die implizite #{header} Karte zu erhalten.

+0

. Indem wir solche Aussagen erneut verwenden, vermischen wir die Sichtweise und die Geschäftslogik, was gegen das Konzept von MVC verstößt. Wie rechtfertigen Sie das? –

+0

@Krsna: Wird es irgendwo in der Geschäftslogik (wieder) verwendet? Dann halte es dort. Wird es ausschließlich in der Ansicht verwendet? Dann schadet es nicht, es im Blick zu behalten. – BalusC

0

Sie könnten diese Validierung für eine Methode mit verwalteten Bean schreiben, um zu überprüfen, ob der User-Agent zur vierten Option passt. Beispiel:

public boolean userAgentUnknownBrowser() { 
// Verify if contains the user-agent String 
} 

Und auf Ihrer Seite, werden Sie nur die Methode verwenden:

<rich:panel id="dlGeneric" rendered="#{myBean.userAgentUnknownBrowser()}"> 
+0

Sie sollten keinen Getter verwenden, um Geschäftslogik zu verarbeiten. –

+0

Oh, Entschuldigung. Die Methode könnte auch einen anderen Namen haben. –

0

Sie

<c:choose> 
<c:when test="#{fn:containsIgnoreCase(request.getHeader('User-Agent'), 'Android')}"> 
<rich:panel id="dlAndroid"> 
... 
</rich:panel> 
</c:when> 
<c:when test="#{fn:containsIgnoreCase(request.getHeader('User-Agent'), 'iPhone')}"> 
<rich:panel id="dlIphone"> 
... 
</rich:panel> 
</c:when> 
<c:otherwise> 
<rich:panel id="dlGeneric"> 
    ... 
</rich:panel> 
</c:otherwise> 
<c:choose> 

verwenden kann ich glauben, eine Logik verwenden die, um zu bestimmen Browser-Typ, der sich nicht zwischen den POSTS auf derselben Seite ändern würde, daher scheint es mir sicher zu sein, JSTL-Tags hier zu verwenden. JSTL-Tag wird nur einmal während der CREATE VIEW für die Seite ausgeführt.

Allerdings, wenn Sie die Bedingung auf einige Modellvariable testen dann ist es besser, jede der Platten in ui zu wickeln: Fragment wie

<ui:fragment rendered="#{fn:containsIgnoreCase(request.getHeader('User-Agent'), 'Android')}"> 
    <rich:panel id="dlAndroid"> 
    ... 
    </rich:panel> 
<ui:fragment> 
Verwandte Themen