Pregunta

Tengo una situación en la que hay un selectOneMenu que tiene un valor vinculado a un bean de respaldo.

Necesito tener un botón que no actualice los valores del modelo (es por eso que tiene la propiedad inmediata = " verdadero ").

El método de acción de ese botón cambia el valor al que está seleccionado selectOneMenu, pero cuando se vuelve a mostrar la página, se muestra el valor original (el que se envió) y no el establecido en el método de acción.

¿Alguna idea de por qué sucede eso?

Si no expliqué el problema lo suficientemente bien, avíseme.


EDITAR: Según lo solicitado aquí está el código fuente en cuestión:

código de página:

<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>

código java:

private Person selectedPerson;

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

La solución está en la línea marcada como SOLUCIÓN :)

¿Fue útil?

Solución

Como sucede con frecuencia unos momentos después de publicar esta pregunta, he encontrado una respuesta:

La causa del problema se explica en detalle aquí: ClearInputComponents

El problema es (como se explicó) que los valores del modelo no se han actualizado, por lo que las entradas enviadas todavía están en el campo component.submittedValue y ese campo se muestra si no está vacío. Se vacía normalmente después de actualizar el modelo.

La primera solución no funcionó en mi caso porque hay otro estado importante en la vista que no debe perderse. Pero la segunda solución funcionó muy bien:

component.setSubmittedValue(null);

Y eso era todo lo que se necesitaba: es un poco de trabajo extra porque los componentes deben estar unidos a algún bean, pero no está tan mal.

Otros consejos

Para seguir un poco, no creo que necesite vincular el componente a un bean. Puede obtener el componente de la instancia de FacesContext a través de UIViewRoot , si conoce el ID de cliente del componente.

Sería algo así:

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

Donde Foo es la clase del componente que está utilizando y clientId es el ID de cliente del componente en " formId: elementId " formato que utiliza JSF.

Para mí, esto ha funcionado:

@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"/>
...

Gracias.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top