To pytanie może być bardziej typu "pojęciowy" lub "Nie rozumiem JSF".Niedozwolona składnia dla operacji zestawu: Jak powiedzieć JSF Nie "chcę" ustawnika
Mój scenariusz: Mam stronę JSF (index.xhtml
), gdzie używam p:accordionPanel
(ale nie sądzę, aby miało to znaczenie, jaki element jest). Chcę go ustawić jako activeIndexes
.
<p:accordionPanel multiple="true" activeIndex="#{myController.getActiveIndexesForSections('whatever')}">
// bla bla...
</p:accordionPanel>
A (uproszczony) metoda w fasoli podkładowej:
public String getActiveIndexesForSections(String holderName){
String activeSections = "";
for(Section s : sectionMap.get(holderName)){
if (s.isActive())
//add to the string
}
return activeSections;
}
Teraz to działa dobrze na normalnej stronie obciążenia.
Ale jeśli klikniesz na p:commandButton
(z ajax=false
) (lub cokolwiek innego, co „wysyła” dane z powrotem do serwera chyba) - pojawia się następujący wyjątek:
/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
Po pewnym googlowania/odczyt komunikat o błędzie stwierdziłem, że potrzebuję setter
.
Po pierwsze: nie chcę setera - czy naprawdę tego potrzebuję, czy jest sposób, aby powiedzieć JSF, że nie chcę tego "zachowania".
Po drugie, zdałem sobie sprawę, że nie jest to "łatwe" dostarczenie setera, ponieważ moja metoda ma parametr (więc public void setActiveIndexesForSections(String name, String activeIndexes)
lub public void setActiveIndexesForSections(String name)
nie zadziała). Co wymyśliłem w końcu jest:
Tworzenie (ogólne) "pseudo-property-klasa":
// 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) {
}
}
zmienić metodę fasoli:
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);
}
i nazwać z index.xhtml
:
<p:accordionPanel multiple="true" activeIndex="#{myController.getActiveIndexesForSections('whatever').val}">
// bla bla...
</p:accordionPanel>
to działa, ale oczywiście jest brzydki hack/wo rkaround.
Jaki jest właściwy sposób radzenia sobie z taką sytuacją? Czy to, co robię, jest po prostu całkowicie błędne?
Dziękuję za to, że okazałeś mi łaskę; (Nie mogę uwierzyć, że ten przypadek użycia jest tak rzadki, że nikt (nie oczekiwał ode mnie) kiedykolwiek chciał to zrobić - więc tak naprawdę zastanawiam się, czy nie zrozumiałem tego wielkiego obrazu ...) - Także mój "akordeonPanel" s są generowane w tagu, gdzie "cokolwiek" jest przekazywane jako parametr - czy mogę nawet użyć parametru jako 'var' z 'c: set', a następnie jako' activeIndex' z 'accordionPanel'? Jeśli tak to jak? –
Właściwym sposobem w tym konkretnym przypadku byłoby zwrócenie niestandardowej implementacji 'Map'. I nie, nie można używać EL w atrybucie "var", więc plik tagu byłby nieprzyjemny. W każdym razie, po sprawdzeniu kodu źródłowego '', zobaczyłem inne obejście, które jest lepsze do wielokrotnego użycia w tagfiles. Zobacz aktualizację odpowiedzi. –
BalusC
Dzięki. Spróbuję tego i jutro również "niestandardową" mapę. A jeśli to zadziała, zaakceptuj + "nagrodę" :) –