2011-07-25 10 views
85

Niedawno zacząłem używać JSF 2.0 z Faceletami i byłem zaskoczony nowymi komponentami kompozytowymi znającymi istniejące <ui:include> i inne techniki szablonowania oferowane przez Facelets 1.x.Kiedy używać <ui:include>, tagować pliki, komponenty kompozytowe i/lub komponenty niestandardowe?

Jaka jest różnica między tymi podejściami? Funkcjonalnie wydają się oferować o tym samym: <ui:param> vs <cc:attribute>, <ui:insert> + <ui:define> vs plików znaczników, ponowne wykorzystanie istniejących szablonów. Czy jest coś poza składnią i wyraźną specyfikacją interfejsu w przypadku komponentów kompozytowych? Czy wydajność może się różnić?

Odpowiedz

152

Jaka jest różnica między tymi podejściami?

Facelet szablony

szablony Korzystanie Facelet (jak w <ui:composition>, <ui:include> i <ui:decorate>), jeśli chcesz podzielić główne fragmenty układu strony do reuseable szablonów. Na przykład. nagłówka, menu, treść, stopka itp

Przykłady:

Pliki znaczników Facelet

Użyj plików znaczników Facelet, jeśli chcesz mieć grupę komponentów wielokrotnego użytku, aby zapobiec/zminimalizować duplikowanie kodu. Na przykład. grupa etykiet + elementy wejściowe + wiadomości. Główną różnicą w stosunku do komponentów kompozytowych jest to, że dane wyjściowe pliku znacznika Facelet nie stanowią pojedynczego UIComponent i mogą w niektórych przypadkach być jedynym rozwiązaniem, gdy komponent złożony nie jest wystarczający. Ogólnie rzecz biorąc, posiadanie <ui:include> z jednym lub więcej <ui:param> jest sygnałem, że plik włączający może być lepiej plikiem znacznika.

Przykłady:

kompozytowe elementy

C przy zastosowaniu Komponenty kompozytowe, jeśli chcesz utworzyć pojedynczy i wielokrotnego użytku niestandardowy UIComponent z jedną odpowiedzialnością za pomocą czystego XML. Taki złożony komponent zwykle składa się z kilku istniejących komponentów i/lub HTML i fizycznie jest renderowany jako pojedynczy komponent i ma być związany z jedną właściwością ziarnistą. Na przykład.komponent, który reprezentuje pojedynczą właściwość java.util.Date przez 3 zależne komponenty <h:selectOneMenu>, lub komponent, który łączy <p:fileUpload> i <p:imageCropper> w pojedynczy obiekt <my:uploadAndCropImage>, określając pojedynczą jednostkę jako właściwość.

Przykłady:

niestandardowe elementy

Użyj niestandardowy składnik, gdy funkcja nie może być osiągnięty z plikami znaczników Facelet lub elementów kompozytowych, ze względu na brak wsparcia w standardzie/dostępny zestaw komponentów. Przykłady można znaleźć we wszystkich miejscach kodu źródłowego bibliotek komponentów open source, takich jak PrimeFaces i OmniFaces.

Tag koparki

Gdy chcesz kontrolować budowanie drzewa komponentów JSF zamiast renderowania wyjścia HTML, należy użyć funkcji obsługi tagu zamiast komponentu.

Przykłady:

Przykładowe projekty

Oto s ome przykładowe projekty, które wykorzystują wszystkie wyżej wymienione techniki.


może wydajność różnią?

Technicznie, problem z wydajnością jest znikomy. Wybór powinien zostać dokonany w oparciu o konkretne wymagania funkcjonalne i ostateczny stopień abstrakcji, możliwości ponownego wykorzystania i łatwości utrzymania wdrożenia. Każde podejście ma swój własny ściśle określony cel i ograniczenia.

Komponenty kompozytowe mają jednak znaczny narzut podczas budowy/przywracania widoku (w szczególności: podczas zapisywania/przywracania stanu widoku). W starszych wersjach programu Mojarra komponenty kompozytowe miały problemy z wydajnością związane z przypisywaniem wartości domyślnych, co zostało już naprawione od wersji 2.1.13. Poza tym, Mojarra miał memory leak, gdy do wyrażeń metod używane jest <cc:attribute method-signature>, w zasadzie całe drzewo komponentów jest ponownie przywoływane w sesji HTTP, jest to poprawione od wersji 2.1.29/2.2.8. Przeciek pamięci może być pominięty w starszych 2.1 wersjach jak poniżej:

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

Albo w starszych 2.2 wersjach jak poniżej:

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

Still, gdy mają stosunkowo „dużo” elementów kompozytowych, a masz javax.faces.STATE_SAVING_METHOD ustawiony na client, wtedy wykonanie będzie cierpieniem. Nie nadużywaj komponentów kompozytowych, jeśli potrzebujesz tylko podstawowej funkcjonalności, która jest już możliwa dzięki prostemu plikowi lub plikowi znaczników. Nie używaj łatwości konfiguracji (czytaj: nie wymaga pliku *.taglib.xml) jako pretekstu do preferowania komponentów kompozytowych w plikach znaczników.

Podczas korzystania Mojarra 2.2.10 lub starsza, nie zapomnij wyłączyć stosunkowo krótkie Facelets okres odświeżania dla trybu produkcji:

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

Nie używaj tego ustawienia dla rozwoju, w przeciwnym razie masz ponowne uruchomienie cały serwer, aby uzyskać odzwierciedlenie zmian w plikach Facetów! Mojarra 2.2.11 i nowsze, a MyFaces domyślnie przyjmuje wartość -1, gdy javax.faces.PROJECT_STAGE nie jest ustawione na Development.

+0

dlaczego chcesz renderować 1 komponent (komponent kompozytowy) zamiast powiedzmy 3 (plik znacznika facelet)? Mam na myśli, że w słoneczny dzień może poczujesz się jak 1 zamiast 3 ... ale myślę, że kryje się za tym coś jeszcze. W twoim przykładzie rozszerzasz UINamingContainer ... czy może to być jeden z powodów, dla których warto wybrać cc (aby móc nadpisać niektóre funkcje specyficzne dla implementacji jsf)? – Toskan

+2

Plik znacznika powinien być traktowany jako rodzaj załącznika. Składnik kompozytowy powinien być postrzegany jako składnik rzeczywisty. Składnik kompozytowy ** wymaga ** do implementacji 'NamingContainer', w przeciwnym razie wystąpią problemy z duplikatem ID, gdy ten sam komponent zostanie wielokrotnie użyty. – BalusC

+0

@ BalusC Załóżmy, że mam pakiet HTML i JSF, które tworzą "blok", który pozwala mi dodawać lub usuwać adresy (i wszystkie jego atrybuty: ulica, numer, miasto itp.). Muszę użyć tego samego bloku na 2 lub 3 stronach. Czy to wchodzi w twój opis Kompozytowego komponentu? – RinaldoPJr