JSF commandButton с immediate= " true"
у меня есть ситуация, когда есть selectOneMenu, который имеет значение, связанное с резервным компонентом.
мне нужна кнопка, которая не обновляет значения модели (поэтому она имеет свойство immediate="true").
метод действия этой кнопки изменяет значение, к которому привязан selectOneMenu, но при повторном отображении страницы отображается исходное значение (то, которое было отправлено), а не то, которое установлено в методе действия.
любые идеи, почему это происходит?
Если я не объяснил проблему достаточно хорошо, пожалуйста, дайте мне знать.
РЕДАКТИРОВАТЬ: По запросу здесь исходный код в вопросе:
код страницы:
<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>
код java:
private Person selectedPerson;
public String createNew() {
log.debug("New created...");
selectedPerson = null;
bindings.getSelectPersonComponent().setSubmittedValue(null); //SOLUTION
return "";
}
решение находится в подкладке с пометкой решение :)
3 ответов
Как это часто бывает через несколько минут после публикации этого вопроса, я нашел ответ:
причина проблемы подробно объясняется здесь:ClearInputComponents
проблема в том (как объяснено), что значения модели не были обновлены, поэтому представленные входы все еще находятся в компоненте.поле submittedValue и это поле отображается, если оно не пустое. Он опорожняется обычно после обновления модели.
первое решение не сработало в моем случае, потому что есть другое важное состояние в представлении, которое не должно потеряться. Но второе решение сработало отлично:
component.setSubmittedValue(null);
и это было все, что нужно: это немного дополнительная работа, потому что компоненты должны быть привязаны к какому-то Бобу, но не так плохо.
чтобы немного проследить, я не думаю, что вам нужно привязать компонент к Бобу. Вы можете просто захватить компонент из FacesContext
инстанс через UIViewRoot
, Если вы знаете идентификатор клиентского компонента.
Это было бы что-то вроде этого:
Foo component = (Foo)FacesContext.getCurrentInstance().getViewRoot().getComponent(clientId);
здесь Foo
- это класс используемого компонента и clientId
- идентификатор клиента компонента в формате "formId: elementId", который использует JSF.
для меня это работает:
@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"/>
...
спасибо.