JSTL в JSF2 Facelets … имеет смысл?

Я хотел бы вывести бит кода Facelets условно.

Для этой цели ярлыки JSTL работают нормально:

 ...  

Однако я не уверен, что это лучшая практика? Есть ли другой способ достичь моей цели?

Введение

Теги JSTL – это все обработчики меток, и они выполняются во время времени сборки , в то время как tags JSF – это все компоненты пользовательского интерфейса, и они выполняются во время просмотра рендеринга .

Обратите внимание, что из собственных тегов и JSF те же, которые не распространяются на UIComponent , также являются обработчиками меток, например , , и т. Д. Те, которые простираются от UIComponent , также являются компонентами пользовательского интерфейса JSF, например , , и т. Д. Из компонентов интерфейса JSF только атрибуты id и binding также оцениваются во время времени сборки , Таким образом, приведенный ниже ответ на жизненный цикл JSTL также применим к атрибутам id и binding компонентов JSF.

Время сборки представления – это тот момент, когда файл XHTML / JSP должен разбираться и преобразовываться в дерево компонентов JSF, которое затем сохраняется как UIViewRoot из FacesContext . Время рендеринга представления – это тот момент, когда дерево компонентов JSF собирается генерировать HTML, начиная с UIViewRoot#encodeAll() . Итак: компоненты JSF UI и tags JSTL не синхронизируются, как вы ожидали от кодирования. Вы можете визуализировать его следующим образом: JSTL запускается сверху вниз, создавая дерево компонентов JSF, затем очередь JSF запускается сверху вниз, создавая вывод HTML.

vs

Например, эта разметка Facelets, итерирующая более 3 элементов с помощью :

    

… создает в течение времени построения три отдельных компонента в дереве компонентов JSF, примерно так:

    

… которые, в свою очередь, индивидуально генерируют свой HTML-вывод во время просмотра рендеринга:

 value1 value2 value3 

Обратите внимание, что вам необходимо вручную убедиться в уникальности идентификаторов компонентов и что они также оцениваются во время времени сборки.

Хотя эта разметка Facelets итерирует более 3 элементов, используя , который является компонентом пользовательского интерфейса JSF:

    

… уже заканчивается как-есть в дереве компонентов JSF, в результате чего тот же компонент находится во время повторного использования времени визуализации представления для генерации вывода HTML на основе текущей итерации round:

 value1 value2 value3 

Обратите внимание, что как компонент NamingContainer уже обеспечил уникальность идентификатора клиента на основе индекса итерации; также невозможно использовать EL в атрибуте id дочерних компонентов таким образом, поскольку он также оценивается во время времени построения, тогда как #{item} доступен только во время отображения рендеринга. То же самое верно для h:dataTable и аналогичных компонентов.

/ vs rendered

В качестве другого примера эта разметка Facelets условно добавляет разные tags, используя (вы также можете использовать для этого):

          

… в случае type = TEXT добавьте только компонент в дерево компонентов JSF:

  

Пока эта разметка Facelets:

    

… будет таким же, как указано выше, в дереве компонентов JSF независимо от условия. Таким образом, это может закончиться «раздутым» деревом компонентов, когда у вас их много, и они фактически основаны на «статической» модели (т. Е. field никогда не изменяется во время, по крайней мере, области обзора). Кроме того, вы можете столкнуться с проблемой EL, когда имеете дело с подclassами с дополнительными свойствами в версиях Mojarra до 2.2.7.

vs

Они не взаимозаменяемы. задает переменную в области EL, которая доступна только после местоположения тега во время создания времени просмотра, но в любом месте в представлении во время визуализации представления. передает переменную EL в шаблон Facelet, включенный через , или . В старых версиях JSF были ошибки, в которых переменная также доступна вне шаблона Facelet, о которой идет речь, на это никогда не следует полагаться.

без атрибута scope будет вести себя как псевдоним. Он не кэширует результат выражения EL в любой области. Таким образом, он может прекрасно использоваться внутри, например, итерации компонентов JSF. Таким образом, например, ниже будет работать нормально:

     

Он не подходит, например, для вычисления суммы в цикле. Для этого вместо этого используйте stream EL 3.0 :

  ...  

Total price: #{bean.products.stream().map(product->product.price).sum()}

Только, когда вы устанавливаете атрибут области с одним из допустимых значений request , view , session или application , тогда он будет оцениваться сразу же во время времени построения и храниться в указанной области.

  

Это будет оцениваться только один раз и доступно как #{dev} протяжении всего приложения.

Используйте JSTL для управления построением дерева компонентов JSF

Использование JSTL может привести к неожиданным результатам при использовании внутри итерационных компонентов JSF, таких как , и т. Д., Или когда атрибуты тега JSTL зависят от результатов событий JSF, таких как preRenderView или представленные значения формы в модель, которая недоступна во время просмотра времени просмотра. Таким образом, используйте tags JSTL только для управления streamом построения дерева компонентов JSF. Используйте компоненты интерфейса JSF для управления streamом генерации вывода HTML. Не связывайте переменную итерации компонентов JSF с атрибутами тега JSTL. Не полагайтесь на события JSF в атрибутах тегов JSTL.

В любое время, когда вы считаете, что вам нужно привязать компонент к бэк-файлу через binding или захватить один с помощью findComponent() , а также создать / обработать его дочерние new SomeComponent() с помощью Java-кода в бэк-компоненте с new SomeComponent() а что нет, тогда вы должны немедленно остановитесь и подумайте об использовании JSTL. Поскольку JSTL также основан на XML, код, необходимый для динамического создания компонентов JSF, станет настолько читаемым и поддерживаемым.

Важно знать, что версии Mojarra старше 2.1.18 имели ошибку в частичном сохранении состояния при ссылке на объект с областью видимости в атрибуте тега JSTL. Весь объект, охваченный областью видимости, будет вновь воссоздаваться, а не извлекаться из дерева представлений (просто потому, что полное дерево просмотра еще не доступно в момент запуска JSTL). Если вы ожидаете или сохраняете какое-либо состояние в области видимого компонента с помощью атрибута тега JSTL, то оно не вернет ожидаемое значение или оно будет «потеряно» в режиме реального вида, который восстанавливается после просмотра дерево построено. Если вы не можете перейти на Mojarra 2.1.18 или новее, то работа вокруг заключается в отключении частичного сохранения состояния в web.xml как web.xml ниже:

  javax.faces.PARTIAL_STATE_SAVING false  

Смотрите также:

  • Каково время построения представления?
  • Как работает атрибут привязки в JSF? Когда и как его использовать?
  • Как отредактировать fragment старого JSP на эквивалент JSF?
  • Должно ли PARTIAL_STATE_SAVING установить значение false?
  • Коммуникация в JSF 2.0 – @ViewScoped не работает в обработчиках тегов

Чтобы увидеть примеры реальных примеров, где tags JSTL полезны (т. Е. Когда они действительно используются при построении представления), см. Следующие вопросы / ответы:

  • Как создать сетку составного компонента JSF?
  • Динамически создавать столбцы таблицы в JSF
  • Как настроить макет h: selectOneRadio
  • Определение условной переменной в JSF
  • Как сделать составной компонент похожим на
  • JSF 2 – композитный компонент с дополнительным атрибутом прослушивателя на f: ajax
  • Вложенные составные компоненты JSF, приводящие к исключению переполнения стека

В двух словах

Что касается вашего конкретного функционального требования, если вы хотите условно отображать компоненты JSF, используйте атрибут #{lpc} на HTML-компоненте JSF, особенно если #{lpc} представляет #{lpc} итерированный элемент #{lpc} -итеративного компонента, такого как или .

  ...  

Или, если вы хотите условно создать компоненты JSF (создать / добавить), продолжайте использовать JSTL. Это намного лучше, чем многословное выполнение new SomeComponent() в java.

   ...   

Смотрите также:

  • Условно отображение компонентов JSF
  • JSTL c: if не работает внутри JSF h: dataTable
  • Указать условный рендеринг элемента внутри ? , похоже, не работает

использование

  ...  

Извините за отдельный ответ, но я не мог комментировать ответы выше.

Для коммутационного вывода вы можете использовать переключатель из простых-расширений .

Interesting Posts

Конфигурация сети VirtualBox

javax.xml.bind.JAXBException: class ***, ни один из его суперclassов не известен этому контексту

getopt не анализирует необязательные аргументы для параметров

Насколько дорогим является RTTI?

Как сравнить два аудиофайла без потерь?

Запретить автозаполнение текстового поля с ранее введенными значениями

SQlite Получение ближайших мест (с широтой и долготой)

Непосредственное создание фиктивной переменной, заданной в разреженной матрице в R

Как выбрать всех дочерних элементов элемента, кроме последнего дочернего элемента?

Эффективный способ rbind data.frames с разными столбцами

Клонирование 2,5-дюймового жесткого диска для ноутбука и SDD на нескольких ноутбуках?

Каков наилучший способ полностью удалить все с компьютера без переустановки?

Значение ios_base :: sync_with_stdio (false); cin.tie (NULL);

Нужно ли мне запускать дефрагментацию на SSD?

Что такое «область» в базовой аутентификации

Давайте будем гением компьютера.