JSF: использовать значения массива в качестве параметров - PullRequest
6 голосов
/ 16 июля 2010

На моей странице JSF2 я использую интернационализированные сообщения об ошибках.

В бэк-бэк я помещаю сообщения во флэш-память Scope:

flash.put("error", exception.getType());

На странице эта строка переводится следующим образом:

<h:outputText value="#{bundle[flash.error]}"/>

Работает нормально.

СЕЙЧАС я хочу иметь возможность добавлять (произвольное количество) параметров в текст сообщения, которые вставляются в заполнители в свойстве i18n в моем сообщении message.properties.Поэтому я помещаю параметры в виде массива String во Flash Scope, например:

//exception.getParameters returns String[]
flash.put("errorParams", exception.getParameters())

Теперь я также хочу иметь возможность использовать этот массив String в качестве параметров для элемента outputFormat, чтобы вставитьих в собственность, как Welcome, {0} {1}.Поэтому я попытался добиться этого с помощью ui: repeat :

<h:outputFormat value="#{bundle[flash.error]}" rendered="#{! empty flash.error}" class="invalid">
  <ui:repeat value="#{flash.errorParams}" var="_param">
    <f:param value="#{bundle[_param]}"/>
    <!-- also doesn't work: <f:param value="#{_param}"/>-->
  </ui:repeat>
</h:outputFormat>

К сожалению, значение параметра игнорируется, а заполнители свойства i18n не заменяются, поэтому визуализированныйвывод Welcome, {0} {1}.При использовании «обычного» повторителя, отображающего элементы массива как выходной текст, это работает.Таким образом, тег outputFormat, по-видимому, не поддерживает использование повторения в качестве дочернего элемента.Черт, так близко;) Кто-нибудь знает хороший способ сделать то, что я хочу, или есть какая-нибудь библиотека компонентов, поддерживающая что-то подобное?

1 Ответ

8 голосов
/ 16 июля 2010

Проблема в том, что ui:repeat - это дочерний элемент времени рендеринга h:outputFormat, который он вообще не поддерживает. Вы хотите поместить несколько элементов f:param непосредственно как дочерние элементы h:outputFormat во время сборки.

c:forEach подходит для этой задачи. Основные теги JSTL (которые уже включены в Facelets, поэтому вам не нужно устанавливать никаких дополнительных JAR-файлов) выполняют свою работу во время построения дерева представлений, прямо перед тем, как JSF переходит в process / рендер дерево представлений.

<html xmlns:c="http://java.sun.com/jsp/jstl/core">
...
<h:outputFormat value="#{bundle[flash.error]}" rendered="#{! empty flash.error}" class="invalid">
  <c:forEach items="#{flash.errorParams}" var="_param">
    <f:param value="#{bundle[_param]}"/>
  </c:forEach>
</h:outputFormat>
...