Câu hỏi này có thể có nhiều loại "khái niệm" hoặc "Tôi không hiểu JSF".Cú pháp bất hợp pháp cho hoạt động thiết lập: Làm thế nào để báo cho JSF tôi không "muốn" một setter
Kịch bản của tôi: Tôi có trang JSF (index.xhtml
) nơi tôi sử dụng p:accordionPanel
(nhưng tôi không nghĩ nó quan trọng đối với thành phần). Những gì tôi muốn làm là đặt activeIndexes
của nó.
<p:accordionPanel multiple="true" activeIndex="#{myController.getActiveIndexesForSections('whatever')}">
// bla bla...
</p:accordionPanel>
Và phương pháp (đơn giản) trong đậu ủng hộ:
public String getActiveIndexesForSections(String holderName){
String activeSections = "";
for(Section s : sectionMap.get(holderName)){
if (s.isActive())
//add to the string
}
return activeSections;
}
Bây giờ này chỉ hoạt động tốt trong một lần tải trang bình thường.
Nhưng nếu tôi bấm vào một p:commandButton
(với ajax=false
) (hoặc bất cứ điều gì khác mà "gửi" dữ liệu lại cho máy chủ tôi đoán) - Tôi nhận được ngoại lệ sau đây:
/WEB-INF/tags/normalTextSection.xhtml @8,112 activeIndex="#{myController.getActiveIndexesForSections(name)}": Illegal Syntax for Set Operation
// bla..
Caused by: javax.el.PropertyNotWritableException: Illegal Syntax for Set Operation
Sau khi một số googling/đọc thông báo lỗi tôi thấy rằng tôi cần một số setter
.
Trước hết: Tôi không muốn người đặt cược - tôi có thực sự cần một hay không có cách nào để nói với JSF Tôi không muốn "hành vi" này.
Thứ hai tôi nhận ra rằng không dễ dàng để cung cấp một setter, bởi vì phương pháp của tôi có một tham số (vì vậy public void setActiveIndexesForSections(String name, String activeIndexes)
hoặc public void setActiveIndexesForSections(String name)
sẽ không hoạt động). Những gì tôi đã đưa ra cuối cùng là:
Tạo (generic) "Pseudo-hữu-class":
// just a dummy class since the class is recreated at every request
public class Property<T> implements Serializable {
private T val;
public Property(T val) {
this.val= val;
}
public T getVal() {
return val;
}
//no need to do anyhting
public void setVal(T val) {
}
}
Thay đổi phương pháp đậu:
public Property<String> getActiveIndexesForSections(String holderName){
String activeSections = "";
for(Section s : sectionMap.get(holderName)){
if (s.isActive())
//add to the string
}
return new Property<String>(activeSections);
}
Và gọi nó là từ số index.xhtml
:
<p:accordionPanel multiple="true" activeIndex="#{myController.getActiveIndexesForSections('whatever').val}">
// bla bla...
</p:accordionPanel>
Điều này hoạt động nhưng rõ ràng là một hack/wo xấu xí rkaround.
Cách thích hợp để xử lý tình huống như thế này là gì? Hoặc là những gì tôi đang làm đơn giản là hoàn toàn sai?
Cảm ơn bạn đã thương xót tôi;) Bạn có đề xuất một cách khác để làm điều đó - vì nó "đơn giản" sai? (Điều tôi không thể tin là, trường hợp sử dụng này hiếm đến mức không ai (mong đợi tôi) muốn làm điều này - vì vậy tôi thực sự băn khoăn liệu mình có hiểu sai hình ảnh lớn ...) - Cũng là 'accordionPanel' của tôi s được tạo ra trong một thẻ mà 'bất cứ điều gì' được thông qua như một tham số - tôi thậm chí có thể sử dụng tham số như'''' của 'c: set' và sau đó là' activeIndex' của 'accordionPanel'? Nếu thế thì sao? –
Cách phù hợp trong trường hợp cụ thể này sẽ trả về bản triển khai 'Bản đồ' tùy chỉnh. Và không, bạn không thể sử dụng EL trong thuộc tính 'var', vì vậy một tagfile sẽ khó chịu. Trong bất kỳ cách nào, sau khi kiểm tra mã nguồn của '', tôi thấy một cách giải quyết khác có thể sử dụng lại tốt hơn trong các tagfiles. Xem cập nhật câu trả lời. –
BalusC
Cảm ơn. Sẽ thử điều này và cũng là 'bản đồ' tùy chỉnh 'vào ngày mai. Và nếu nó hoạt động chấp nhận + "bounty" bạn :) –