Newsgroup: it.comp.java
Titolo: I misteri del FacesContext

Salve a tutti,
ho un problema abbastanza banale da risolvere in teoria ma in pratica
con JSF son dolori...
Ho una combo che deve presentare a video un sottoinsieme di una
Collection in base ad un valore di un'altra combo (Provincie vs
Regioni per capirci).
Per fare ciò, il mio getter - getProvincie() - che restituisce un
List<SelectItem> "legge" attraverso il binding dell'HtmlSelectOneMenu
relativo alle regioni il suo value ed in base a questo valore produce
il sottoinsieme.
Il problema si presenta quando io cambio la regione e voglio il
riaggiornamento della combo delle provincie.
Infatti, facendo partire il submit con un onchange() sulla combo delle
regioni, io ottengo lo stesso la nuova combo delle provincie MA, anche
un errore di validazione sulla combo medesimo.
Ora spiego il perchè ed anche il motivo del titolo di questo thread.
Al submit, infatti, dopo le fasi di RESTORE_VIEW e
APPLY_REQUEST_VALUES parte quella di PROCESS_VALIDATIONS che invoca
una PRIMA volta getProvincie().
Successivamente, avendo avuto errori di validazione su altri campi
della pagina, si ripassa subito a quella di RENDER_RESPONSE che invoca
una SECONDA volta getProvincie().
Entrambe le invocazioni restituiscono la stessa lista (quella nuova)
in quanto la nuovo combo delle regioni (con il suo nuovo selected) ha
già effettuato il binding. L'errore di validazione è quindi causato
dal fatto che la PRIMA invocazione NON trova più i valori che la combo
aveva prima.
Per ovviare a ciò, e cioè fare in modo tale che alla prima invocazione
getProvincie() non mi renda un sottoinsieme ma TUTTE le provincie
(comprese quindi quelle presenti precedentemente) devo "testare" la
fase in cui il metodo viene invocato.
A tale scopo, sembrava atto allo scopo il metodo getRenderResponse()
di FacesContext
(FacesContext.getCurrentInstance().getRenderResponse()) che, mi sarei
aspettato, avrebbe restituito false nella fase di PROCESS_VALIDATIONS
e true in quella di RENDER_RESPONSE.
Invece, restituisce sempre true!
Anzi, ho anche "acceso" un PhaseListener sull'applicazione nei cui
metodi beforePhase(PhaseEvent event) e afterPhase(PhaseEvent event),
invocati da JSF stesso, faccio stampare il valore di
getRenderResponse() tramite
event.getFacesContext().getRenderResponse()
ebbene, il risultato soprendente è questo:
ValPhaseListener.beforePhase(ValPhaseListener.java:90) - DEBUG -
before - PROCESS_VALIDATIONS 3
ValPhaseListener.beforePhase(ValPhaseListener.java:91) - DEBUG -
isRenderResponse? :false
AnagraficaForm.getProvincie(AnagraficaForm.java:293) - DEBUG -
isRenderResponse? :true
ValPhaseListener.afterPhase(ValPhaseListener.java:39) - DEBUG - after
- PROCESS_VALIDATIONS 3
ValPhaseListener.afterPhase(ValPhaseListener.java:40) - DEBUG -
isRenderResponse? :true
ValPhaseListener.beforePhase(ValPhaseListener.java:90) - DEBUG -
before - RENDER_RESPONSE 6
ValPhaseListener.beforePhase(ValPhaseListener.java:91) - DEBUG -
isRenderResponse? :true
AnagraficaForm.getProvincie(AnagraficaForm.java:293) - DEBUG -
isRenderResponse? :true
ValPhaseListener.afterPhase(ValPhaseListener.java:39) - DEBUG - after
- RENDER_RESPONSE 6
ValPhaseListener.afterPhase(ValPhaseListener.java:40) - DEBUG -
isRenderResponse? :true
Come potete vedere, nella fase di PROCESS_VALIDATIONS all'interno di
beforePhase ho false, subito dopo, cioè nel mio managed bean, è già a
true.
Due domande:
1) come è possibile che già nella fase di PROCESS_VALIDATIONS io abbia
true?
2) come risolvo il mio problema? Ossia, come faccio a capire quando il
mio getProvincie deve generare il nuovo sottoinsieme e quando no?
Grazie a tutti.

 
Esegui il codice dentro una action con questo trucchetto:
<h:selectOneMenu 
....onchange="document.getElementById('form:link').click();">
...
<h:commandLink id="link" action="#{bean.action}" style="display:none;"/>

 
pion...@inwind.it
 ha scritto:

Scusami, ma forse non hai afferrato bene il problema.
Le combo figlie devono essere popolate (con i figli del padre
selezionato) ANCHE se io non vario il padre. Insomma, se io ho Lazio
come Regione, ad ogni submit che non mi fa cambiare pagina devo vedere
solo 5 provincie.
Ergo, il metodo che estrae i figli deve partire SEMPRE e non solo
quando cambio qualcosa.
Il problema è che questo metodo estrae i figli da subito già nella
fase di validazione E quando cambio il valore del padre, i nuovi figli
prendono subito il posto dei vecchi invece che solo nella fase di
Response, e questo a jsf non piace.
Oltretutto, perchè mi hai consigliato quel trucco quando avrei invece
disponibile il valueChangeListener?
Penso che sulla scia di questo articolo
http://balusc.blogspot.com/2007/10/populate-child-menus.html
lavorerò con immediate="true" e forzerò io la chiamata alla fase di
Response

 Response
Se hai davvero bisogno di questo credo che JSF sia un fallimento. Ma 
dubito che sia l'unica strada come ti dicevo.

 dubito che sia l'unica strada come ti dicevo.
Alla fine ho scelto una via di mezzo: i subset in sessione e la
rigenerazione con il listener.
Certo, secondo me ricorrere alla sessione ogni volta che devi fare
qualcosa che invece Struts ti permetteva di fare con la request...non
è un buon segno.