Как визуализировать компонент только в том случае, если другой компонент не отображается?

У меня есть страница, которую пользователь может получить через Android, iPhone, BlackBerry или через неизвестный браузер. У меня 4 rich:panel s, по одному для каждой платформы, а последний - общий.

Код:

<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? <--- }">

Как я могу сделать последний rich:panel только в том случае, если ни один из остальных не был отображен?

Ответ 1

К тому же, ваш вопрос, указанный в заголовке, может быть определен как:

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

Однако в этом конкретном случае, возможно, более приятным было бы обозначать те длинные изгибы с помощью <c:set>:

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

Обратите внимание, что существует более короткий способ получить заголовок запроса с помощью неявной карты #{header}.

Ответ 2

Вы можете написать эту проверку на управляемом методе bean, чтобы он проверил, соответствует ли пользовательский агент 4-й опции. Пример:

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

И на вашей странице вы просто используете метод:

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

Ответ 3

Вы можете использовать

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

Я думаю, что вы используете логику, чтобы определить тип браузера, который не изменился бы между POSTS на той же странице, поэтому мне кажется безопасным использовать здесь тег JSTL. Тег JSTL будет выполняться только один раз во время CREATE VIEW для страницы.

Однако, если вы тестируете условие на некоторой переменной модели, лучше обернуть каждую из панелей в ui: фрагмент, например

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