Конкатенация строк в выражении EL, определенных в атрибуте тега facelets
Мне нужно написать выражение EL для атрибута, который выглядит примерно так:
#{cc.attrs.appreciatedByCurrentUser ? (cc.attrs.count +'<br/>'+ (cc.attrs.count-1)) : ((cc.attrs.count+1) +'<br/>'+ cc.attrs.count)}
Теперь проблема заключается в том, что это дает ошибку, поскольку строки не могут быть объединены, как я это делаю. Итак, как я могу это исправить?
Я использую JSF 2.0 с facelets.
EDIT:
Я решаю проблему, используя следующий встроенный javascript
<script type="text/javascript">
var count=#{cc.attrs.count};
document.write(#{cc.attrs.appreciatedByCurrentUser} ? (count-1) +'<br/>'+count : count+'<br/>'+ (count+1));
</script>
Можете ли вы придумать какую-либо проблему с этим?
Ответы
Ответ 1
Конкатенация строк в EL возможна только путем вложения в выражение. Оператор +
находится в EL исключительно оператором sum. Кроме того, <
и >
являются недопустимыми символами в XML-атрибутах, поэтому вам нужно их избежать (и инструктируйте <h:outputText>
, чтобы не ускользнуть от них еще раз escape="false"
):
<h:outputText value="#{cc.attrs.count}<br/>#{cc.attrs.count-1}" escape="false" rendered="#{cc.attrs.appreciatedByCurrentUser}" />
<h:outputText value="#{cc.attrs.count+1}<br/>#{cc.attrs.count}" escape="false" rendered="#{!cc.attrs.appreciatedByCurrentUser}" />
В качестве альтернативы вы также можете использовать <c:set>
для псевдонима выражения:
<c:set var="appreciated" value="#{cc.attrs.count}<br/>#{cc.attrs.count-1}" />
<c:set var="notAppreciated" value="#{cc.attrs.count+1}<br/>#{cc.attrs.count}" />
<h:outputText value="#{cc.attrs.appreciatedByCurrentUser ? appreciated : notAppreciated}" escape="false" />
Ответ 2
Можно объединить строки в EL с помощью метода java.lang.String.concat(String)
. Таким образом, ваш код может выглядеть так:
<h:outputText value="#{cc.attrs.appreciatedByCurrentUser ? (''.concat(cc.attrs.count).concat('<br/>').concat(cc.attrs.count-1)) : (''.concat((cc.attrs.count+1)).concat('<br/>').concat(cc.attrs.count))}" escape="false" />
В этом конкретном случае, однако, я бы пошел с одним из вариантов, предложенным г-ном BalusC, потому что вышеприведенный код выглядит не очень элегантным. В некоторых случаях знание этой техники может быть полезно.
Я вряд ли рекомендую использовать javascript в качестве обходного пути здесь.
Ответ 3
Это единственное, что я могу придумать.
<h:panelGroup rendered="#{cc.attrs.appreciatedByCurrentUser}">
<h:outputText value="#{(cc.attrs.count)}" style="display:block;" />
<h:outputText value="#{(cc.attrs.count-1)}" />
</h:panelGroup>
<h:panelGroup rendered="#{not cc.attrs.appreciatedByCurrentUser}">
<h:outputText value="#{(cc.attrs.count+1)}" style="display:block;" />
<h:outputText value="#{(cc.attrs.count)}" />
</h:panelGroup>
Помещение <br>
в атрибут value всегда будет вызывать ошибки в JSF, поэтому вам нужно будет использовать display:block
.