อะไรคือความแตกต่างระหว่างแนวทางเหล่านี้?
เทมเพลต Facelet
ใช้ Facelet แม่ (ในขณะที่<ui:composition>
, <ui:include>
และ<ui:decorate>
) ถ้าคุณต้องการที่จะแยกชิ้นส่วนหลักเค้าโครงหน้าเป็นแม่แบบ Reuseable เช่นส่วนหัวเมนูเนื้อหาส่วนท้าย ฯลฯ
ตัวอย่าง:
ไฟล์แท็ก Facelet
ใช้ไฟล์แท็ก Facelet หากคุณต้องการมีกลุ่มส่วนประกอบที่ใช้ซ้ำได้เพื่อป้องกัน / ลดการทำซ้ำรหัส เช่นกลุ่มของป้ายกำกับ + อินพุต + คอมโพเนนต์ข้อความ ความแตกต่างที่สำคัญกับส่วนประกอบคอมโพสิตคือผลลัพธ์ของไฟล์แท็ก Facelet ไม่ได้แสดงถึงไฟล์เดียวUIComponent
และในบางสถานการณ์อาจเป็นทางออกเดียวเมื่อส่วนประกอบคอมโพสิตไม่เพียงพอ โดยทั่วไปการ<ui:include>
มีอย่างน้อยหนึ่งรายการ<ui:param>
ซึ่งส่งผ่านคุณสมบัติ bean ที่มีการจัดการ (และไม่ใช่ค่าฮาร์ดโค้ด) เป็นสัญญาณว่าไฟล์รวมสามารถเป็นไฟล์แท็กได้ดีกว่า
ตัวอย่าง:
ส่วนประกอบคอมโพสิต
ใช้คอมโพสิตคอมโพเนนต์หากคุณต้องการสร้างแบบกำหนดเองUIComponent
เดียวและใช้ซ้ำได้ด้วยความรับผิดชอบเดียวโดยใช้ XML ที่บริสุทธิ์ ส่วนประกอบคอมโพสิตดังกล่าวมักประกอบด้วยส่วนประกอบและ / หรือ HTML ที่มีอยู่จำนวนมากและได้รับการแสดงผลทางกายภาพเป็นองค์ประกอบเดียวและควรถูกผูกไว้กับคุณสมบัติ bean เดียว เช่นคอมโพเนนต์ที่แสดงjava.util.Date
คุณสมบัติเดียวโดย 3 <h:selectOneMenu>
องค์ประกอบที่ขึ้นต่อกันหรือส่วนประกอบที่รวม<p:fileUpload>
และ<p:imageCropper>
เป็นองค์ประกอบเดียวที่<my:uploadAndCropImage>
อ้างอิงcom.example.Image
เอนทิตีแบบกำหนดเองเดียวเป็นคุณสมบัติ
ตัวอย่าง:
ส่วนประกอบที่กำหนดเอง
ใช้ส่วนประกอบที่กำหนดเองเมื่อใดก็ตามที่ไม่สามารถใช้งานได้กับไฟล์แท็ก Facelet หรือส่วนประกอบคอมโพสิตเนื่องจากไม่มีการสนับสนุนในชุดส่วนประกอบมาตรฐาน / ที่มีอยู่ ตัวอย่างสามารถพบได้ทั่วสถานที่ทั้งหมดในรหัสที่มาของห้องสมุดองค์ประกอบที่มาเปิดเช่นPrimeFacesและOmniFaces
เครื่องจัดการแท็ก
เมื่อคุณต้องการควบคุมการสร้างโครงสร้างคอมโพเนนต์ JSF แทนการแสดงผลเอาต์พุต HTML คุณควรใช้เครื่องจัดการแท็กแทนส่วนประกอบ
ตัวอย่าง:
ตัวอย่างโครงการ
ต่อไปนี้เป็นโครงการตัวอย่างที่ใช้เทคนิคที่กล่าวมาทั้งหมด
ประสิทธิภาพอาจแตกต่างกันหรือไม่?
ในทางเทคนิคแล้วความกังวลเกี่ยวกับประสิทธิภาพนั้นมีน้อยมาก ทางเลือกควรขึ้นอยู่กับข้อกำหนดการทำงานที่เป็นรูปธรรมและระดับสุดท้ายของนามธรรมการนำกลับมาใช้ใหม่และการบำรุงรักษาของการนำไปใช้งาน แต่ละแนวทางมีวัตถุประสงค์และข้อ จำกัด ที่ชัดเจนของตัวเอง
อย่างไรก็ตามส่วนประกอบคอมโพสิตมีค่าใช้จ่ายที่สำคัญในระหว่างการสร้าง / กู้คืนมุมมอง (โดยเฉพาะ: ระหว่างการบันทึก / กู้คืนสถานะมุมมอง) และใน Mojarra เวอร์ชันเก่าส่วนประกอบคอมโพสิตมีปัญหาด้านประสิทธิภาพในการกำหนดค่าเริ่มต้นซึ่งได้รับการแก้ไขแล้วตั้งแต่ 2.1.13 นอกจากนี้ Mojarra ยังมีหน่วยความจำรั่วเมื่อใช้ a <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
.