Командная кнопка JSF с немедленным=“true”
-
03-07-2019 - |
Вопрос
У меня есть ситуация, когда есть 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 "";
}
Раствор находится в выровненном маркированном РЕШЕНИЕ :)
Решение
Как это часто бывает, через несколько минут после публикации этого вопроса я нашел ответ:
Причина проблемы подробно объяснена здесь: Компоненты CLEARINPUT
Проблема заключается (как объяснено) в том, что значения модели не были обновлены, поэтому отправленные входные данные все еще находятся в поле component.submittedValue, и это поле отображается, если оно не пустое.Обычно он очищается после обновления модели.
Первое решение не сработало в моем случае, потому что в представлении есть другое важное состояние, которое не должно быть потеряно.Но второе решение сработало отлично:
component.setSubmittedValue(null);
И это было все, что было нужно:это небольшая дополнительная работа, потому что компоненты должны быть привязаны к какому-то компоненту, но не так уж плохо.
Другие советы
Чтобы немного проследить, я не думаю, что вам нужно привязывать компонент к bean.Вы можете просто взять компонент из 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"/>
...
Спасибо.