Kapan menggunakan <ui: include>, file tag, komponen komposit, dan / atau komponen kustom?

102

Saya mulai menggunakan JSF 2.0 dengan Facelet baru-baru ini dan bingung dengan komponen komposit baru yang mengetahui <ui:include>teknik template yang ada dan lainnya yang ditawarkan oleh Facelet 1.x.

Apa perbedaan antara pendekatan tersebut? Secara fungsional mereka tampaknya menawarkan hampir sama: file tag <ui:param>vs <cc:attribute>, <ui:insert>+ <ui:define>vs, penggunaan kembali dari template yang ada. Apakah ada selain sintaks dan spesifikasi antarmuka yang jelas untuk komponen komposit? Bisakah kinerja berbeda?

mrembisz
sumber

Jawaban:

176

Apa perbedaan antara pendekatan tersebut?

Template facelet

Gunakan templat Facelet (seperti dalam <ui:composition>, <ui:include>dan <ui:decorate>) jika Anda ingin membagi fragmen tata letak halaman utama menjadi templat yang dapat digunakan kembali. Misalnya header, menu, konten, footer, dll.

Contoh:

File tag facelet

Gunakan file tag Facelet jika Anda ingin memiliki grup komponen yang dapat digunakan kembali untuk mencegah / meminimalkan duplikasi kode. Misalnya sekelompok label + input + komponen pesan. Perbedaan utama dengan komponen komposit adalah bahwa keluaran file tag Facelet tidak mewakili satu pun UIComponentdan dalam beberapa keadaan mungkin menjadi satu-satunya solusi jika komponen komposit tidak mencukupi. Secara umum, memiliki <ui:include>dengan satu atau lebih <ui:param>yang melewati properti kacang yang dikelola (dan dengan demikian bukan nilai hardcode) adalah sinyal bahwa file yang disertakan dapat menjadi file tag dengan lebih baik.

Contoh:

Komponen komposit

Gunakan komponen komposit jika Anda ingin membuat kustom tunggal dan dapat digunakan kembali UIComponentdengan satu tanggung jawab menggunakan XML murni. Komponen komposit seperti itu biasanya terdiri dari sekumpulan komponen yang ada dan / atau HTML dan secara fisik dirender sebagai komponen tunggal dan seharusnya terikat ke satu properti kacang. Misalnya, komponen yang mewakili satu java.util.Dateproperti dengan 3 <h:selectOneMenu>komponen dependen , atau komponen yang menggabungkan <p:fileUpload>dan <p:imageCropper>menjadi satu <my:uploadAndCropImage>referensi com.example.Imageentitas kustom tunggal sebagai properti.

Contoh:

Komponen khusus

Gunakan komponen kustom setiap kali fungsionalitas tidak dapat dicapai dengan file tag Facelet atau komponen komposit, karena kurangnya dukungan dalam kumpulan komponen standar / yang tersedia. Contoh dapat ditemukan di semua tempat dalam kode sumber pustaka komponen sumber terbuka seperti PrimeFaces dan OmniFaces .

Penangan tag

Jika Anda ingin mengontrol pembangunan pohon komponen JSF daripada merender output HTML, Anda harus menggunakan penangan tag, bukan komponen.

Contoh:

Contoh proyek

Berikut adalah beberapa contoh proyek yang memanfaatkan semua teknik yang disebutkan di atas.


Bisakah kinerja berbeda?

Secara teknis, masalah kinerja dapat diabaikan. Pilihan harus dibuat berdasarkan persyaratan fungsional konkrit dan tingkat akhir dari abstraksi, dapat digunakan kembali, dan dapat dipelihara dari implementasi. Setiap pendekatan memiliki tujuan dan batasan yang didefinisikan dengan baik.

Namun komponen komposit memiliki overhead yang signifikan selama membangun / memulihkan tampilan (khususnya: selama menyimpan / memulihkan status tampilan). Dan, di versi Mojarra yang lebih lama, komponen komposit memiliki masalah performa dengan penetapan nilai default, ini sudah diperbaiki sejak 2.1.13. Selain itu, Mojarra mengalami kebocoran memori ketika a <cc:attribute method-signature>digunakan untuk ekspresi metode, pada dasarnya seluruh pohon komponen direferensikan dalam sesi HTTP, ini diperbaiki sejak 2.1.29 / 2.2.8. Kebocoran memori dapat dilewati dalam versi 2.1 yang lebih lama seperti di bawah ini:

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

Atau di versi 2.2 yang lebih lama seperti di bawah ini:

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

Namun, bila Anda memiliki relatif "banyak" komponen komposit, dan Anda telah javax.faces.STATE_SAVING_METHODmengaturnya client, maka kinerjanya akan merepotkan. Jangan menyalahgunakan komponen komposit jika Anda hanya menginginkan fungsionalitas dasar yang sudah dimungkinkan dengan file penyertaan atau file tag sederhana. Jangan gunakan kemudahan konfigurasi (baca: tidak *.taglib.xmlperlu file) sebagai alasan untuk lebih memilih komponen komposit daripada file tag.

Saat menggunakan Mojarra 2.2.10 atau yang lebih lama, jangan lupa untuk menonaktifkan periode refresh Facelet yang relatif singkat untuk mode produksi:

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

Jangan gunakan pengaturan ini untuk pengembangan, jika tidak, Anda harus me-restart seluruh server untuk mendapatkan perubahan pada file Facelet untuk diterapkan! Mojarra 2.2.11 dan yang lebih baru, dan MyFaces sudah default ke -1saat javax.faces.PROJECT_STAGEtidak disetel ke Development.

BalusC
sumber
mengapa Anda ingin merender 1 komponen (komponen komposit) daripada katakanlah 3 (file tag facelet)? Maksud saya, pada hari yang cerah Anda mungkin merasa seperti 1, bukan 3 ... tapi saya rasa ada hal lain di baliknya. Dalam contoh Anda, Anda memperluas UINamingContainer ... mungkinkah itu salah satu alasan untuk menggunakan cc (agar dapat menimpa beberapa fungsi spesifik implementasi jsf)?
Toskan
2
File tag harus dilihat sebagai semacam penyertaan. Komponen komposit harus dilihat sebagai komponen nyata. Sebuah komponen komposit membutuhkan untuk melaksanakan NamingContainer, jika tidak, anda berakhir dengan masalah ID duplikat ketika komponen yang sama digunakan kembali beberapa kali.
BalusC
@BalusC Katakanlah saya memiliki sekumpulan HTML dan JSF yang membuat 'blok' yang memungkinkan saya untuk menambah atau menghapus Alamat (dan semua atributnya: jalan, bilangan, kota, dll). Saya perlu menggunakan blok yang sama dalam 2 atau 3 halaman. Apakah itu termasuk dalam deskripsi Anda tentang Komponen Komposit?
RinaldoPJr
1
@ Rinaldo: Saya pikir saya akan menggunakan file tag untuk itu dengan ID komponen yang diisi secara dinamis seperti yang ditunjukkan di stackoverflow.com/questions/5713718/… . IMO, jika itu bisa dilakukan dengan file tag, gunakan itu. Jika tidak dapat dilakukan dengan file tag, gunakan komposit. Jika Anda memerlukan banyak komponen untuk memanipulasi satu properti (bukan alamat, tetapi misalnya nama jalan + nomor rumah yang harus masuk dalam satu properti), maka komponen komposit akan menjadi satu-satunya solusi.
BalusC
2
@Tarik: komposit memiliki banyak overhead dibandingkan dengan tagfile. Dengan kata lain: kinerja yang buruk. Gunakan hanya jika Anda perlu membuat satu komponen UI khusus berdasarkan sekumpulan komponen yang sudah ada dan terkait erat. Ini tidak dapat dilakukan dengan tagfile. ZEEF.com, misalnya hanya memiliki satu komposit: upload / download / crop image all-in-one yang digunakan dalam gambar halaman ao, gambar profil, header blok link, blok gambar, dll. Itu terikat hanya pada sebuah Imageproperti dalam kacang.
BalusC