Объект valueChangeListener
будет вызываться только тогда, когда форма отправлена и отправленное значение отличается от начального значения. Таким образом, он не вызывается, когда запускается толькоchange
событие HTML DOM . Если вы хотите отправить форму во время change
события HTML DOM , вам нужно будет добавить другую <f:ajax/>
форму без слушателя (!) К компоненту ввода. Это вызовет отправку формы, которая обрабатывает только текущий компонент (как в execute="@this"
).
<h:selectOneMenu value="#{bean.value}" valueChangeListener="#{bean.changeListener}">
<f:selectItems ... />
<f:ajax />
</h:selectOneMenu>
При использовании <f:ajax listener>
вместо valueChangeListener
, он по умолчанию будет выполняться уже во время change
события HTML DOM . Внутри UICommand
компонентов и компонентов ввода, представляющих флажок или радиокнопку, по умолчанию он будет выполняться только во время click
события HTML DOM .
<h:selectOneMenu value="#{bean.value}">
<f:selectItems ... />
<f:ajax listener="#{bean.ajaxListener}" />
</h:selectOneMenu>
Еще одно важное отличие заключается в том, что valueChangeListener
метод вызывается в конце PROCESS_VALIDATIONS
фазы. На данный момент отправленное значение еще не обновлено в модели. Таким образом, вы не можете получить его, просто обратившись к свойству bean-компонента, которое привязано к входному компоненту value
. Вам нужно это пройти ValueChangeEvent#getNewValue()
. Кстати, старое значение также доступно по адресу ValueChangeEvent#getOldValue()
.
public void changeListener(ValueChangeEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
}
<f:ajax listener>
Метод вызывается во время INVOKE_APPLICATION
фазы. В этот момент отправленное значение уже обновлено в модели. Вы можете просто получить его, напрямую обратившись к свойству bean-компонента, которое привязано к входному компоненту value
.
private Object value;
public void ajaxListener(AjaxBehaviorEvent event) {
System.out.println(value);
}
Кроме того, если вам нужно будет обновить другое свойство на основе отправленного значения, это приведет к сбою при использовании, valueChangeListener
поскольку обновленное свойство может быть переопределено отправленным значением на последующем UPDATE_MODEL_VALUES
этапе. Именно поэтому вы видите в старых приложениях / учебных пособиях / ресурсах JSF 1.x, что valueChangeListener
такая конструкция используется в сочетании с immediate="true"
и FacesContext#renderResponse()
для предотвращения этого. В конце концов, использование valueChangeListener
для выполнения бизнес-действий на самом деле всегда было обходным путем.
Резюме: используйте valueChangeListener
только в том случае, если вам нужно перехватить само изменение фактического значения. Т.е. вас действительно интересуют как старое, так и новое значение (например, их регистрировать).
public void changeListener(ValueChangeEvent event) {
changeLogger.log(event.getOldValue(), event.getNewValue());
}
Используйте <f:ajax listener>
только в том случае, если вам нужно выполнить бизнес-действие с новым измененным значением. Т.е. вас действительно интересует только новое значение (например, для заполнения второго раскрывающегося списка).
public void ajaxListener(AjaxBehaviorEvent event) {
selectItemsOfSecondDropdown = populateItBasedOn(selectedValueOfFirstDropdown);
}
Если вы на самом деле также заинтересованы в старом значении при выполнении бизнес-действия, тогда вернитесь к фазе valueChangeListener
, но поставьте ее в INVOKE_APPLICATION
очередь.
public void changeListener(ValueChangeEvent event) {
if (event.getPhaseId() != PhaseId.INVOKE_APPLICATION) {
event.setPhaseId(PhaseId.INVOKE_APPLICATION);
event.queue();
return;
}
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
System.out.println(newValue.equals(value));
}
logger.trace( "setting changeTypes from {} to {}", this.changeTypes, changeTypes );
. Похоже, вы могли бы использовать старые и новые значения, полученные таким образом, для выполнения бизнес-логики непосредственно в установщике, а также для простого ведения журнала, но я не знаю, вызовет ли это побочные эффекты ...