Объект 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 );
. Похоже, вы могли бы использовать старые и новые значения, полученные таким образом, для выполнения бизнес-логики непосредственно в установщике, а также для простого ведения журнала, но я не знаю, вызовет ли это побочные эффекты ...для первого фрагмента (атрибут прослушивателя ajax):
Атрибут «слушателя» тега ajax - это метод, который вызывается на стороне сервера каждый раз, когда функция ajax выполняется на стороне клиента. Например, вы можете использовать этот атрибут, чтобы указать функцию на стороне сервера, вызываемую каждый раз, когда пользователь нажимает клавишу.
но второй фрагмент (valueChangeListener):
ValueChangeListener будет вызываться только при отправке формы, а не при изменении значения ввода.
* вы можете посмотреть этот удобный ответ
источник