Questa domanda potrebbe essere più del tipo "concettuale" o "Non capisco JSF".Sintassi non valida per l'operazione Set: Come dire a JSF che non "voglio" un setter
mio scenario: Ho una pagina JSF (index.xhtml
), dove io uso un p:accordionPanel
(ma non credo che sia importante quale componente è). Quello che voglio fare è impostare il activeIndexes
di esso.
<p:accordionPanel multiple="true" activeIndex="#{myController.getActiveIndexesForSections('whatever')}">
// bla bla...
</p:accordionPanel>
E il metodo (semplificato) nel backing bean:
public String getActiveIndexesForSections(String holderName){
String activeSections = "";
for(Section s : sectionMap.get(holderName)){
if (s.isActive())
//add to the string
}
return activeSections;
}
Ora questo funziona bene su un carico normale pagina.
Ma se clicco su un p:commandButton
(con ajax=false
) (o qualsiasi altra cosa che "invia" i dati al server immagino) - ottengo la seguente eccezione:
/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
Dopo un po 'googling/lettura il messaggio di errore ho trovato che ho bisogno di un setter
.
Prima di tutto: non voglio un setter - ne ho davvero bisogno o c'è un modo per dire a JSF che non voglio questo "comportamento".
In secondo luogo mi sono reso conto che non è "facile" fornire un setter, perché il mio metodo ha un parametro (quindi public void setActiveIndexesForSections(String name, String activeIndexes)
o public void setActiveIndexesForSections(String name)
non funzionerà). Quello che mi è venuta alla fine è:
Creare un (generico) "Pseudo-proprietà-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) {
}
}
Cambiare il metodo di fagioli:
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);
}
e chiamarlo dal index.xhtml
:
<p:accordionPanel multiple="true" activeIndex="#{myController.getActiveIndexesForSections('whatever').val}">
// bla bla...
</p:accordionPanel>
Questo funziona, ma, ovviamente, è un brutto hack/wo rkaround.
Qual è il modo corretto di gestire una situazione come questa? O è quello che sto facendo semplicemente completamente sbagliato?
Grazie per avere pietà di me;) Consiglieresti un altro modo per farlo - dal momento che "semplicemente" è sbagliato? (Quello che non posso credere è che questo caso d'uso è così raro che nessuno (mi aspetto) abbia mai voluto farlo - quindi mi sto davvero chiedendo se ho capito male il quadro generale ...) - Anche il mio 'accordionPanel' s sono generati all'interno di un tag in cui 'qualunque cosa' viene passato come parametro - posso persino usare il parametro come 'var'of di 'c: set' e quindi come' activeIndex' di 'accordionPanel'? Se é cosi, come? –
Il modo corretto in questo caso specifico sarebbe restituire un'implementazione personalizzata di 'Map'. E no, non puoi usare EL nell'attributo 'var', quindi un tagfile sarebbe cattivo. In ogni caso, dopo aver esaminato il codice sorgente di '', ho visto un'altra soluzione alternativa che è meglio riusabile nei tagfile. Vedi l'aggiornamento della risposta. –
BalusC
Grazie. Proveremo questo e anche la mappa 'personalizzata' di domani. E se funziona accetta + "taglia" tu :) –