Domanda

Ho una situazione in cui esiste un selectOneMenu che ha un valore associato a un backing bean.

Devo avere un pulsante che non aggiorna i valori del modello (ecco perché ha proprietà immediate = " true ").

Il metodo di azione di quel pulsante modifica il valore a cui è associato selectOneMenu, ma quando viene visualizzata nuovamente la pagina viene visualizzato il valore originale (quello che è stato inviato) e non quello impostato nel metodo di azione.

Qualche idea sul perché ciò accada?

Se non ho spiegato il problema abbastanza bene per favore fatemelo sapere.


MODIFICARE: Come richiesto qui è il codice sorgente in questione:

codice pagina:

<h:selectOneMenu id="selectedPerson" 
                 binding="#{bindings.selectPersonComponent}" 
                 value="#{bean.selectedPerson}">
   <s:selectItems var="op" value="#{bean.allPersons}" 
                  label="#{op.osoba.ime} #{op.osoba.prezime}" 
                  noSelectionLabel="#{messages.selectAPerson}">
   </s:selectItems>
   <f:converter converterId="unmanagedEntityConverter" />
</h:selectOneMenu>
...
<a4j:commandButton action="#{bean.createNew}" value="#{messages.createNew}"
     immediate="true" reRender="panelImovine">
</a4j:commandButton>

codice java:

private Person selectedPerson;

public String createNew() {
    log.debug("New created...");
    selectedPerson = null;
    bindings.getSelectPersonComponent().setSubmittedValue(null); //SOLUTION
    return "";
}

La soluzione è nella linea contrassegnata SOLUZIONE :)

È stato utile?

Soluzione

Come spesso accade pochi istanti dopo aver pubblicato questa domanda, ho trovato una risposta:

La causa del problema è spiegata in dettaglio qui: ClearInputComponents

Il problema è (come spiegato) che i valori del modello non sono stati aggiornati, quindi gli input inviati sono ancora nel campo component.submittedValue e quel campo viene visualizzato se non vuoto. Viene svuotato normalmente dopo l'aggiornamento del modello.

La prima soluzione non ha funzionato nel mio caso perché nella vista c'è un altro stato importante che non deve perdersi. Ma la seconda soluzione ha funzionato alla grande:

component.setSubmittedValue(null);

E questo era tutto ciò che serviva: è un po 'più di lavoro perché i componenti devono essere associati ad un bean, ma non così male.

Altri suggerimenti

Per seguire un po ', non penso che sia necessario associare il componente a un bean. Puoi semplicemente prendere il componente dall'istanza FacesContext tramite UIViewRoot , se conosci l'ID client del componente.

Andrebbe un po 'qualcosa del genere:

Foo component = (Foo)FacesContext.getCurrentInstance().getViewRoot().getComponent(clientId);

Dove Foo è la classe del componente che si sta utilizzando e clientId è l'ID client del componente in " formId: elementId " formato utilizzato da JSF.

Per me ha funzionato:

@ManagedBean(name = "bean")
@ViewScoped
public class Bean {
    private SelectOneMenu component;

    public SelectOneMenu getComponent() {
        return selectComponent;
    }

    public void setComponent(SelectOneMenu component) {
        this.Component = component;
    }
    public void resetComponent() {
        component.resetValue();
    }
    ...
}
<h:selectOneRadio value="#{bean.value}" id = "idRadio" required="true" requiredMessage = "Required Message" binding="#{bean.component}" >
    <f:selectItem itemLabel="Value 1" itemValue="value1"/>
    <f:selectItem itemLabel="Value 2" itemValue="value2" />     
</h:selectOneRadio>

<primefaces:commandButton action="#{bean.resetComponent}" value="Erase" update="idRadio" immediate="true"/>
...

Grazie.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top