Quando utilizzare <ui: include>, file di tag, componenti compositi e / o componenti personalizzati?


102

Ho iniziato a utilizzare JSF 2.0 con Facelets di recente e sono rimasto sconcertato dai nuovi componenti compositi che conoscevano le <ui:include>tecniche esistenti e di altro tipo offerte da Facelets 1.x.

Qual è la differenza tra questi approcci? Funzionalmente sembrano offrire più o meno lo stesso: <ui:param>vs <cc:attribute>, <ui:insert>+ <ui:define>vs file di tag, riutilizzo dei modelli esistenti. C'è qualcosa oltre alla sintassi e alle chiare specifiche dell'interfaccia in caso di componenti compositi? Le prestazioni potrebbero differire?

Risposte:


176

Qual è la differenza tra questi approcci?

Modelli di facelet

Usa i modelli Facelet (come in <ui:composition>, <ui:include>e <ui:decorate>) se vuoi dividere i frammenti del layout della pagina principale in modelli riutilizzabili. Ad esempio intestazione, menu, contenuto, piè di pagina, ecc.

Esempi:

File di tag facelet

Utilizza i file dei tag Facelet se desideri disporre di un gruppo di componenti riutilizzabili per prevenire / ridurre al minimo la duplicazione del codice. Ad esempio un gruppo di componenti etichetta + input + messaggio. La principale differenza con i componenti compositi è che l'output di un file di tag Facelet non rappresenta un singolo UIComponente in alcune circostanze può essere l'unica soluzione quando un componente composito non è sufficiente. Generalmente, avere un <ui:include>con uno o più file<ui:param> che passa una proprietà del bean gestito (e quindi non un valore hardcoded) è un segnale che il file include può essere meglio un file di tag.

Esempi:

Componenti compositi

Usa componenti compositi se vuoi creare un custom unico e riutilizzabile UIComponentcon un'unica responsabilità usando XML puro. Un tale componente composito di solito consiste in un gruppo di componenti esistenti e / o HTML e viene reso fisicamente come singolo componente e si suppone che sia associato a una singola proprietà del bean. Ad esempio un componente che rappresenta una singola java.util.Dateproprietà da 3 <h:selectOneMenu>componenti dipendenti , o un componente che combina <p:fileUpload>e <p:imageCropper>in un unico <my:uploadAndCropImage>riferimento a una singola abitudinecom.example.Image entità come proprietà.

Esempi:

Componenti personalizzati

Utilizzare un componente personalizzato ogni volta che la funzionalità non può essere ottenuta con file di tag Facelet o componenti compositi, a causa della mancanza di supporto nel set di componenti standard / disponibile. Esempi possono essere trovati ovunque nel codice sorgente di librerie di componenti open source come PrimeFaces e OmniFaces .

Gestori di tag

Quando si desidera controllare la creazione dell'albero dei componenti JSF invece del rendering dell'output HTML, è necessario utilizzare un gestore di tag invece di un componente.

Esempi:

Progetti di esempio

Ecco alcuni progetti di esempio che utilizzano tutte le tecniche sopra menzionate.


Le prestazioni potrebbero differire?

Tecnicamente, la preoccupazione per le prestazioni è trascurabile. La scelta dovrebbe essere fatta sulla base dei requisiti funzionali concreti e del grado finale di astrazione, riusabilità e manutenibilità dell'implementazione. Ogni approccio ha il proprio scopo e i propri limiti ben definiti.

I componenti compositi hanno tuttavia un sovraccarico significativo durante la costruzione / ripristino della vista (in particolare: durante il salvataggio / ripristino dello stato di visualizzazione). E, nelle versioni precedenti di Mojarra, i componenti compositi avevano problemi di prestazioni con l'assegnazione dei valori predefiniti, questo è già stato risolto dalla 2.1.13. Inoltre, Mojarra ha avuto una perdita di memoria quando a <cc:attribute method-signature>viene utilizzato per le espressioni del metodo, fondamentalmente l'intero albero dei componenti viene ri-referenziato nella sessione HTTP, questo è stato risolto dalla 2.1.29 / 2.2.8. La perdita di memoria può essere aggirata nelle versioni 2.1 precedenti come di seguito:

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

O nelle versioni 2.2 precedenti come di seguito:

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

Tuttavia, quando si hanno relativamente "molti" componenti compositi e si è javax.faces.STATE_SAVING_METHODimpostato suclient , le prestazioni saranno un dolore. Non abusare dei componenti compositi se desideri semplicemente la funzionalità di base che è già possibile con un semplice file include o tag. Non utilizzare la facilità di configurazione (leggi: nessun *.taglib.xmlfile necessario) come scusa per preferire i componenti compositi ai file di tag.

Quando si utilizza Mojarra 2.2.10 o versioni precedenti, non dimenticare di disabilitare il periodo di aggiornamento dei Facelets relativamente breve per la modalità di produzione:

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

Non utilizzare questa impostazione per lo sviluppo, altrimenti devi riavviare l'intero server per far sì che le modifiche nei file Facelets si riflettano! Mojarra 2.2.11 e versioni successive e MyFaces è già impostato su -1quando javax.faces.PROJECT_STAGEnon è impostato su Development.


perché dovresti renderizzare 1 componente (componente composito) invece di diciamo 3 (file di tag facelet)? Voglio dire, in una giornata di sole forse ti sentirai 1 invece di 3 ... ma immagino che dietro ci sia qualcos'altro. Nel tuo esempio stai estendendo UINamingContainer ... potrebbe essere questo uno dei motivi per scegliere un cc (in modo da poter sovrascrivere alcune funzioni specifiche dell'implementazione jsf)?
Toskan

2
Un file di tag dovrebbe essere visto come una sorta di inclusione. Un componente composito dovrebbe essere visto come un componente reale. Un componente composito richiede di attuare NamingContainer, altrimenti si finisce con problemi di ID duplicati quando lo stesso componente viene riutilizzata più volte.
BalusC

@BalusC Diciamo che ho un sacco di HTML e JSF che creano un "blocco" che mi permette di aggiungere o rimuovere indirizzi (e tutti i suoi attributi: via, numero, città, ecc.). Devo usare lo stesso blocco in 2 o 3 pagine. Rientra nella tua descrizione di un componente composito?
RinaldoPJr

1
@Rinaldo: Penso che userei un file di tag per quello con ID dei componenti popolati dinamicamente come dimostrato in stackoverflow.com/questions/5713718/… . IMO, se può essere fatto con un file di tag, usalo. Se non è possibile farlo con un file di tag, utilizzare un file composito. Se avessi bisogno di più componenti per manipolare una singola proprietà (non l'indirizzo, ma ad es. Streetname + numero civico che dovrebbe andare in una singola proprietà), allora un componente composto sarebbe l'unica soluzione.
BalusC

2
@Tarik: i compositi hanno molto overhead rispetto ai tagfile. In altre parole: scarso rendimento. Usalo solo se devi creare un singolo componente dell'interfaccia utente personalizzato basato su una serie di componenti esistenti strettamente correlati. Questo non può essere fatto con un tagfile. ZEEF.com, ad esempio, ha un solo composito: il caricamento / download / ritaglio dell'immagine tutto in uno che viene utilizzato in un'immagine della pagina, nell'immagine del profilo, nell'intestazione del blocco di collegamento, nei blocchi di immagini, ecc. È associato solo a una Imageproprietà in fagioli.
BalusC
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.