JSTL в Jsf2 Facelets ... имеет смысл?
Я хотел бы вывести немного кода Facelets условно.
для этой цели теги JSTL, похоже, работают нормально:
<c:if test="${lpc.verbose}">
...
</c:if>
однако, я не уверен, что это лучшая практика? Есть ли другой способ достичь моей цели?
3 ответа:
введение
JSTL
<c:xxx>
теги taghandlers и они выполняются во время посмотреть время сборки, в то время как JSF<h:xxx>
теги компоненты пользовательского интерфейса и они выполняются во время вид отображения времени.обратите внимание, что из собственного JSF
<f:xxx>
и<ui:xxx>
теги только те, которые делают не продлить отUIComponent
также являются taghandlers, например<f:validator>
,<ui:include>
,<ui:define>
и т. д. Те, которые простираются отUIComponent
также JSF компонентов пользовательского интерфейса, например,<f:param>
,<ui:fragment>
,<ui:repeat>
и т. д. Из компонентов JSF UI толькоid
иbinding
атрибуты также оцениваются во время построения представления. Таким образом, приведенный ниже ответ относительно жизненного цикла JSTL также относится кid
иbinding
атрибуты компонентов JSF.время сборки представления - это тот момент, когда файл XHTML/JSP должен быть проанализирован и преобразован в дерево компонентов JSF который затем сохраняется как
UIViewRoot
наFacesContext
. Время визуализации представления - это тот момент, когда дерево компонентов JSF собирается генерировать HTML, начиная сUIViewRoot#encodeAll()
. Так: JSF компонентов пользовательского интерфейса и тегов JSTL не работает в синхронизации, как вы ожидаете от кодирования. Вы можете визуализировать его следующим образом: JSTL сначала запускается сверху вниз, создавая дерево компонентов JSF, затем очередь JSF снова запускается сверху вниз, создавая вывод HTML.
<c:forEach>
vs<ui:repeat>
например, эта разметка Facelets повторяет 3 элемента с помощью
<c:forEach>
:<c:forEach items="#{bean.items}" var="item"> <h:outputText id="item_#{item.id}" value="#{item.value}" /> </c:forEach>
...создает во время просмотра сборки три отдельных
<h:outputText>
компоненты в дереве компонентов JSF, примерно представленные следующим образом:<h:outputText id="item_1" value="#{bean.items[0].value}" /> <h:outputText id="item_2" value="#{bean.items[1].value}" /> <h:outputText id="item_3" value="#{bean.items[2].value}" />
...которые, в свою очередь, индивидуально генерируют свой HTML-вывод во время просмотра render time:
<span id="item_1">value1</span> <span id="item_2">value2</span> <span id="item_3">value3</span>
обратите внимание, что вам необходимо вручную обеспечить уникальность идентификаторов компонентов и что они также являются оценивается во время построения представления.
в то время как эта разметка Facelets повторяется над 3 элементами с помощью
<ui:repeat>
, который является компонентом пользовательского интерфейса JSF:<ui:repeat id="items" value="#{bean.items}" var="item"> <h:outputText id="item" value="#{item.value}" /> </ui:repeat>
...уже заканчивается как есть в дереве компонентов JSF, где тот же самый
<h:outputText>
компонент находится во время просмотра рендерингаповторно для создания вывода HTML на основе текущего цикла итерации:<span id="items:0:item">value1</span> <span id="items:1:item">value2</span> <span id="items:2:item">value3</span>
отметим, что
<ui:repeat>
какNamingContainer
компонент уже обеспечили уникальность идентификатора клиента на основе индекса итерации; также невозможно использовать EL вid
атрибут дочерних компонентов таким образом, как он также оценивается во время построения представления во время#{item}
доступно только во время просмотра время рендеринга. Же самое верно и дляh:dataTable
и подобных компонентов.
<c:if>
/<c:choose>
vsrendered
в качестве другого примера, эта разметка Facelets условно добавляет разные теги с помощью
<c:if>
(вы также можете использовать<c:choose><c:when><c:otherwise>
для это):<c:if test="#{field.type eq 'TEXT'}"> <h:inputText ... /> </c:if> <c:if test="#{field.type eq 'PASSWORD'}"> <h:inputSecret ... /> </c:if> <c:if test="#{field.type eq 'SELECTONE'}"> <h:selectOneMenu ... /> </c:if>
...в случае
type = TEXT
добавить только<h:inputText>
компонент в дереве компонентов JSF:<h:inputText ... />
пока это Facelets разметка:
<h:inputText ... rendered="#{field.type eq 'TEXT'}" /> <h:inputSecret ... rendered="#{field.type eq 'PASSWORD'}" /> <h:selectOneMenu ... rendered="#{field.type eq 'SELECTONE'}" />
...в конечном итоге точно так же, как и выше, в дереве компонентов JSF независимо от условия. Таким образом, это может оказаться в "раздутом" дереве компонентов, когда у вас их много, и они фактически основаны на "статической" модели (т. е.
field
никогда не меняется, по крайней мере, в области видимости). Кроме того, вы можете столкнуться с EL проблемы когда вы имеете дело с подклассами с дополнительными свойствами в Mojarra до версии 2.2.7.
<c:set>
vs<ui:param>
они не заменимы. Элемент
<c:set>
задает переменную в области EL, которая доступна только после расположение тега во время построения представления, но в любом месте представления во время отображения представления. Элемент<ui:param>
передает переменную EL в шаблон Facelet, включенный через<ui:include>
,<ui:decorate template>
или<ui:composition template>
. Более старые версии JSF имели ошибки, при которых<ui:param>
переменная также доступна за пределами рассматриваемого шаблона Facelet, на это никогда не следует полагаться.The
<c:set>
без
извините за отдельный ответ, но я не могу комментировать ответы выше.
для переключател-подобного выхода вы можете использовать переключатель от primefaces-extensions.