Когда использовать <ui: include>, файлы тегов, составные компоненты и / или пользовательские компоненты?

Я недавно начал использовать JSF 2.0 с Facelets и был озадачен новыми составными компонентами, зная, что существует <ui:include> и другие приемы шаблонирования, предлагаемые Facelets 1.x.

В чем разница между этими подходами? Функционально они, кажется, предлагают примерно то же самое: <ui:param> против <cc:attribute>, <ui:insert>+<ui:define> vs файлы тегов, повторное использование существующих шаблонов. Есть ли что-нибудь кроме синтаксиса и четкой спецификации интерфейса в случае составных компонентов? Может ли производительность отличаться?

1 ответ

Решение

В чем разница между этими подходами?

Шаблоны Facelet

Используйте шаблоны Facelet (как в <ui:composition>, <ui:include> а также <ui:decorate>), если вы хотите разбить фрагменты макета главной страницы на многократно используемые шаблоны. Например, заголовок, меню, содержимое, нижний колонтитул и т. Д.

Примеры:

Файлы тегов Facelet

Используйте файлы тегов Facelet, если вы хотите иметь повторно используемую группу компонентов, чтобы предотвратить / минимизировать дублирование кода. Например, группа компонентов метка + вход + сообщение. Основное отличие от составных компонентов заключается в том, что выходные данные файла тега Facelet не представляют UIComponent и в некоторых случаях может быть единственным решением, когда составного компонента недостаточно. Как правило, имея <ui:include> с одним или несколькими <ui:param> является сигналом того, что включаемый файл может быть файлом тегов.

Примеры:

Композитные компоненты

Используйте составные компоненты, если вы хотите создать единый и многократно используемый UIComponent с единственной ответственностью, используя чистый XML. Такой составной компонент обычно состоит из группы существующих компонентов и / или HTML и физически отображается как отдельный компонент, и предполагается, что он связан с одним свойством компонента. Например, компонент, который представляет собой один java.util.Date собственность на 3 зависимых <h:selectOneMenu> компоненты, или компонент, который объединяет <p:fileUpload> а также <p:imageCropper> в один <my:uploadAndCropImage> ссылаясь на один обычай com.example.Image сущность как собственность.

Примеры:

Пользовательские компоненты

Используйте пользовательский компонент всякий раз, когда функциональность не может быть достигнута с помощью файлов тегов Facelet или составных компонентов из-за отсутствия поддержки в стандартном / доступном наборе компонентов. Примеры можно найти повсюду в исходном коде библиотек компонентов с открытым исходным кодом, таких как PrimeFaces и OmniFaces.

Обработчики тегов

Если вы хотите управлять построением дерева компонентов JSF вместо рендеринга вывода HTML, вам следует использовать обработчик тега вместо компонента.

Примеры:

Примеры проектов

Вот несколько примеров проектов, в которых используются все вышеперечисленные методы.


Может ли производительность отличаться?

Технически проблема производительности незначительна. Выбор должен быть сделан на основе конкретных функциональных требований и конечной степени абстракции, возможности повторного использования и ремонтопригодности реализации. Каждый подход имеет свою четко определенную цель и ограничения.

Однако составные компоненты имеют значительные накладные расходы при создании / восстановлении представления (в частности, при сохранении / восстановлении состояния представления). И в более старых версиях Mojarra у составных компонентов были проблемы с производительностью при назначении значений по умолчанию, это уже исправлено с 2.1.13. Кроме того, у Мохарры была утечка памяти, когда <cc:attribute method-signature> используется для выражений методов, в основном на HTTP-сеанс ссылается все дерево компонентов, это исправлено с 2.1.29 / 2.2.8. Утечка памяти может быть обойдена в более старых версиях 2.1, как показано ниже:

<context-param>
    <param-name>com.sun.faces.serializeServerState</param-name>
    <param-value>true</param-value>
</context-param>

Или в более старых версиях 2.2, как показано ниже:

<context-param>
    <param-name>javax.faces.SERIALIZE_SERVER_STATE</param-name>
    <param-value>true</param-value>
</context-param>

Тем не менее, когда у вас есть относительно "много" составных компонентов, и у вас есть javax.faces.STATE_SAVING_METHOD установлен в client тогда спектакль будет мучительным. Не злоупотребляйте составными компонентами, если вы просто хотите получить базовую функциональность, которая уже возможна с простым включаемым файлом или файлом тега. Не используйте простоту настройки (читай: нет *.taglib.xml файл необходим) в качестве предлога, чтобы предпочесть композитные компоненты над файлами тегов.

При использовании Mojarra 2.2.10 или более ранней версии не забудьте отключить относительно короткий период обновления Facelets для производственного режима:

<context-param>
    <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
    <param-value>-1</param-value>
</context-param>

Не используйте этот параметр для разработки, иначе вам придется перезапустить весь сервер, чтобы изменения в файлах Facelets были отражены! Mojarra 2.2.11 и новее, а MyFaces по умолчанию уже -1 когда javax.faces.PROJECT_STAGE не установлен в Development,

Другие вопросы по тегам