Как реализовать некоторую логику «если-то» с помощью JSF и Facelets?

У меня есть компонент с полем status. В зависимости от значения status для его рендеринга следует применять разные классы css.

Итак, мне нужно что-то вроде этого (очень далеко от псевдокода реальных вещей):

if status == "Approved"
     cssClass = "green"
if status == "Rejected"
     cssClass = "red"
<span class="cssClass">Some info</span>

Я пытался применить jstl, но не могу заставить его работать с фейслетами и jsf (но я слышал, что это возможно, может быть, это правда). Вот код:

<c:choose>
    <c:when test="#{report.approved}">
        <c:set var="statusClass" value="approved"/>
    </c:when>
    <c:when test="#{report.rejected}">
        <c:set var="statusClass" value="rejected"/>
    </c:when>
    <c:when test="#{report.inProgress}">
        <c:set var="statusClass" value="progress"/>
    </c:when>
    <c:when test="#{report.pendingHR}">
        <c:set var="statusClass" value="pending"/>
    </c:when>
</c:choose>
<span class="status ${statusClass}">#{report.formattedStatus}</span>

Как это сделать с JSF/Facelets?


person Roman    schedule 03.08.2010    source источник


Ответы (3)


Чтобы дать преимущество обеим сторонам (модели и представлению), скорее используйте enum вместо четырех независимых логических значений, что в конечном итоге может привести только к проблемам с обслуживанием.

public enum Status {
    APPROVED, REJECTED, PROGRESS, PENDING;
}

С ним не только намного проще и чище работать на стороне Java, но вы также можете просто распечатать его на EL.

<span class="#{bean.status}" />
person BalusC    schedule 03.08.2010
comment
Без проверки не будет ли toString() по-прежнему заглавной? - person Thorbjørn Ravn Andersen; 03.08.2010
comment
Да, это будет. Не должно быть так много работы, чтобы соответствующим образом обновить CSS. - person BalusC; 03.08.2010

Подход JSF обычно использует атрибут rendered в h-тегах. Также обратите внимание, что EL (язык выражений) довольно выразительный в JSF, поэтому вы можете использовать ?: в своем выражении класса. Например.

<span class="status #{report.approved ? 'approved' : report.rejected ? 'rejected' : report.inProgress ? 'progress' : report.pendingHR ? 'pending' : ''}">
person Thorbjørn Ravn Andersen    schedule 03.08.2010
comment
Ух ты, StackOverflow автоматически преобразует подсказки в код :) - person Thorbjørn Ravn Andersen; 03.08.2010

Просто сделайте cssStatus свойством вспомогательного компонента, который разрешается в правильный класс CSS.

public String getCssStatus() {
    if( this.status == .... )
       return "green";
    else 
       ...
}

А потом

<span class="status #{report.cssStatus}">#{report.formattedStatus}</span>

AFAIK, это должно сработать.

person ewernli    schedule 03.08.2010
comment
Я думал об этом, но я все еще надеюсь, что существует лучшее решение. Я бы не хотел связывать имена классов css с java-кодом в bean-компонентах. - person Roman; 03.08.2010
comment
@ Роман, я не вижу ничего плохого в этом подходе. Вы не хотите связывать имя класса с их фактическим рендерингом, что является точкой зрения CSS, но мне кажется, что логика представления решает, какой класс отображать. Несмотря ни на что, где-то будет некоторая логика представления, которая выберет класс CSS на основе статуса отчета. Пока эта логика представления находится на уровне представления, все в порядке. - person ewernli; 03.08.2010
comment
Я могу себе представить, что никто не хочет загромождать модель спецификой просмотра. - person BalusC; 03.08.2010