2011-07-25 33 views
85

Tôi bắt đầu sử dụng JSF 2.0 với Facelets gần đây và bị bối rối bởi các thành phần tổng hợp mới biết hiện có <ui:include> và các kỹ thuật tạo khuôn mẫu khác được cung cấp bởi Facelets 1.x.Khi nào sử dụng <ui:include>, tệp thẻ, thành phần hỗn hợp và/hoặc thành phần tùy chỉnh?

Sự khác nhau giữa các cách tiếp cận đó là gì? Về mặt chức năng, chúng dường như cung cấp như nhau: <ui:param> vs <cc:attribute>, <ui:insert> + <ui:define> so với tệp thẻ, sử dụng lại các mẫu hiện có. Có điều gì ngoài cú pháp và đặc tả giao diện rõ ràng trong trường hợp các thành phần tổng hợp không? Hiệu suất có thể khác nhau không?

Trả lời

152

Sự khác nhau giữa các cách tiếp cận đó là gì?

mẫu Facelet

Sử dụng Facelet mẫu (như trong <ui:composition>, <ui:include><ui:decorate>) nếu bạn muốn chia mảnh vỡ bố cục trang chính vào các mẫu reuseable. Ví dụ. tiêu đề, menu, nội dung, chân vv

Ví dụ:

Tệp thẻ Facelet

Sử dụng tệp thẻ Facelet nếu bạn muốn có một nhóm thành phần có thể dùng lại để ngăn chặn/giảm thiểu trùng lặp mã. Ví dụ. một nhóm các thành phần nhãn + đầu vào + tin nhắn. Sự khác biệt chính với các thành phần tổng hợp là đầu ra của tệp thẻ Facelet không đại diện cho một UIComponent và có thể trong một số trường hợp là giải pháp duy nhất khi một thành phần tổng hợp không đủ. Nói chung, có một số <ui:include> với một hoặc nhiều <ui:param> là tín hiệu cho biết tệp bao gồm có thể là tệp thẻ tốt hơn.

Ví dụ:

thành phần composite

Sử dụng c các thành phần omposite nếu bạn muốn tạo một tùy chỉnh đơn lẻ và có thể tái sử dụng UIComponent với một trách nhiệm duy nhất bằng cách sử dụng XML thuần túy. Thành phần hỗn hợp này thường bao gồm một loạt các thành phần hiện có và/hoặc HTML và được kết xuất vật lý dưới dạng một thành phần duy nhất và được cho là ràng buộc với một thuộc tính bean đơn. Ví dụ.một thành phần đại diện cho một thuộc tính java.util.Date duy nhất bởi 3 thành phần phụ thuộc <h:selectOneMenu> hoặc một thành phần kết hợp <p:fileUpload><p:imageCropper> thành một đơn <my:uploadAndCropImage> giới thiệu một thực thể duy nhất là thuộc tính là com.example.Image.

Ví dụ:

Các thành phần tùy chỉnh

Sử dụng thành phần tùy chỉnh bất cứ khi nào chức năng không thể đạt được với tập tin thẻ Facelet hoặc thành phần hỗn hợp, do thiếu bộ phụ kiện chuẩn/có sẵn. Có thể tìm thấy các ví dụ trên tất cả các vị trí trong mã nguồn của các thư viện thành phần nguồn mở như PrimeFacesOmniFaces.

Tag xử lý

Khi bạn muốn kiểm soát việc xây dựng cây thành phần JSF thay vì vẽ của đầu ra HTML, sau đó bạn nên sử dụng một trình xử lý thẻ thay vì một thành phần.

Ví dụ:

Ví dụ dự án

Dưới đây là s các dự án mẫu ví dụ sử dụng tất cả các kỹ thuật được đề cập ở trên.


hiệu suất có thể khác nhau?

Về mặt kỹ thuật, mối quan tâm hiệu suất là không đáng kể. Sự lựa chọn nên được thực hiện dựa trên các yêu cầu chức năng cụ thể và mức độ trừu tượng cuối cùng, khả năng sử dụng lại và khả năng bảo trì của việc thực hiện. Mỗi phương pháp đều có mục đích và hạn chế được xác định rõ ràng.Tuy nhiên,

Thành phần tổng hợp có chi phí đáng kể trong khi xây dựng/khôi phục chế độ xem (cụ thể: trong khi lưu/khôi phục trạng thái xem). Và, trong các phiên bản cũ của Mojarra, các thành phần tổng hợp có các vấn đề về hiệu suất với việc gán các giá trị mặc định, điều này đã được khắc phục kể từ 2.1.13. Ngoài ra, Mojarra có một số memory leak khi một số <cc:attribute method-signature> được sử dụng cho các biểu thức phương thức, về cơ bản toàn bộ cây thành phần được tham chiếu lại trong phiên HTTP, điều này được khắc phục kể từ 2.1.29/2.2.8. Vụ rò rỉ bộ nhớ có thể được bỏ qua trong 2,1 phiên bản cũ như sau:

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

Hoặc trong 2,2 phiên bản cũ như sau:

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

Tuy nhiên, khi bạn có tương đối "rất nhiều" thành phần composite, và bạn có javax.faces.STATE_SAVING_METHOD được đặt thành client, sau đó hiệu suất sẽ là một cơn đau. Không lạm dụng các thành phần hỗn hợp nếu bạn chỉ muốn chức năng cơ bản đã có sẵn với một tệp tin hoặc tệp thẻ đơn giản bao gồm. Không sử dụng cấu hình dễ dàng (đọc: không cần *.taglib.xml tệp) như một cái cớ để thích các thành phần tổng hợp hơn các tệp thẻ.

Khi sử dụng cá móm 2.2.10 trở lên, đừng quên để vô hiệu hóa Facelets tương đối ngắn làm mới thời gian cho phương thức sản xuất:

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

Không sử dụng cài đặt này cho phát triển, nếu không bạn đã khởi động lại toàn bộ máy chủ để có được những thay đổi trong các tập tin Facelets được phản ánh! Mojarra 2.2.11 trở lên và MyFaces đã mặc định là -1 khi javax.faces.PROJECT_STAGE không được đặt thành Development.

+0

tại sao bạn muốn hiển thị 1 thành phần (thành phần hỗn hợp) thay vì giả sử 3 (tệp thẻ facelet)? Ý tôi là, vào một ngày nắng, bạn có thể cảm thấy như 1 thay vì 3 ... nhưng tôi đoán có cái gì đó khác đằng sau nó. Trong ví dụ của bạn bạn đang mở rộng UINamingContainer ... có thể đó là một trong những lý do để đi cho một cc (để có thể ghi đè lên một số chức năng cụ thể thực hiện jsf)? – Toskan

+2

Tệp thẻ phải được xem là loại bao gồm. Một thành phần tổng hợp nên được xem như là một thành phần thực sự. Thành phần hỗn hợp ** yêu cầu ** để triển khai 'NamingContainer', nếu không bạn sẽ gặp phải các vấn đề trùng lặp ID khi cùng một thành phần được sử dụng lại nhiều lần. – BalusC

+0

@BalusC Giả sử tôi có một bó HTML và JSF tạo một 'khối' cho phép tôi thêm hoặc xóa Địa chỉ (và tất cả các thuộc tính của nó: đường phố, số, thành phố, v.v.). Tôi cần phải sử dụng cùng một khối trong 2 hoặc 3 trang. Điều đó có nằm trong mô tả của bạn về một Component Composite không? – RinaldoPJr

Các vấn đề liên quan