Коли використовувати <ui: include>, файли тегів, складені компоненти та / або користувацькі компоненти?


102

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

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

Відповіді:


176

Яка різниця між цими підходами?

Шаблони фейлеток

Використовуйте 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. Крім того, у Myrra виникла пам'ять, коли <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.


чому б ви хотіли візуалізувати 1 компонент (складений компонент), а не скажімо 3 (файл тегів фасетки)? Я маю на увазі добре, у сонячний день ви, можливо, відчуватимете себе 1, а не 3 ... але я думаю, що щось ще за цим. У вашому прикладі ви розширюєте UINamingContainer ... Чи може це бути однією з причин звернутися до cc (щоб мати змогу замінити деякі функції, які реалізують jsf)?
Тоскан

2
Файл тегів слід розглядати як вид включення. Складний компонент слід розглядати як реальний компонент. Складний компонент потребує реалізації NamingContainer, інакше у вас виникають проблеми з ідентифікацією дублікатів, коли один і той же компонент повторно використовується багато разів.
BalusC

@BalusC Скажімо, у мене є купа HTML та JSF, які створюють "блок", який дозволяє мені додавати або видаляти адреси (і всі його атрибути: вулиця, номер, місто тощо). Мені потрібно використовувати той самий блок на 2 або 3 сторінках. Чи підпадає це під ваш опис складового компонента?
RinaldoPJr

1
@Rinaldo: Я думаю, я би використовував файл тегів для цього з динамічно заповненими ідентифікаторами компонентів, як, як показано в stackoverflow.com/questions/5713718/… . IMO, якщо це можна зробити з файлом тегів, використовуйте його. Якщо це неможливо зробити з файлом тегів, використовуйте композит. Якщо вам потрібно декілька компонентів для маніпулювання однією властивістю (не адреса, але, наприклад, назва вулиці + housenumber, яка повинна входити в одну властивість), то складений компонент буде єдиним рішенням.
BalusC

2
@Tarik: композити мають багато накладних витрат порівняно з тегфілами. Іншими словами: низька продуктивність. Використовуйте його лише в тому випадку, якщо вам потрібно створити єдиний користувальницький компонент інтерфейсу на основі набору тісно пов'язаних існуючих компонентів. Це неможливо зробити з файлом тегів. Наприклад, ZEEF.com має лише один композиційний елемент: завантажувати / завантажувати / обрізати зображення "все-в-одному", що використовується у зображенні на сторінці сторінок, зображення профілю, заголовку блоку посилань, блоках зображень тощо. Це пов'язано лише з Imageвластивістю в квасолі.
BalusC
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.