는 valueChangeListener
유일한 양식이 제출 될 때 호출됩니다 및 제출 값은 초기 값과 다릅니다. 따라서 HTML DOM 이벤트 만 실행될 때 호출되지 않습니다 change
. HTML DOM change
이벤트 중에 양식을 제출하려면 <f:ajax/>
listener (!)없이 다른 양식 을 입력 구성 요소 에 추가해야합니다 . 현재 구성 요소 만 처리하는 양식 제출이 발생합니다 (에서와 같이 execute="@this"
).
<h:selectOneMenu value="#{bean.value}" valueChangeListener="#{bean.changeListener}">
<f:selectItems ... />
<f:ajax />
</h:selectOneMenu>
<f:ajax listener>
대신을 사용하면 valueChangeListener
기본적으로 HTML DOM change
이벤트 중에 이미 실행됩니다 . UICommand
확인란 또는 라디오 버튼을 나타내는 구성 요소 및 입력 구성 요소 내부 에서는 기본적으로 HTML DOM click
이벤트 중에 만 실행 됩니다.
<h:selectOneMenu value="#{bean.value}">
<f:selectItems ... />
<f:ajax listener="#{bean.ajaxListener}" />
</h:selectOneMenu>
또 다른 주요 차이점은 단계 valueChangeListener
가 끝날 때 메서드가 호출 된다는 것 PROCESS_VALIDATIONS
입니다. 이때 제출 된 값은 아직 모델에서 업데이트되지 않았습니다. 따라서 입력 구성 요소에 바인딩 된 빈 속성에 액세스하는 것만으로는 얻을 수 없습니다 value
. 으로 가져와야합니다 ValueChangeEvent#getNewValue()
. 그런데 이전 값은에서도 사용할 수 있습니다 ValueChangeEvent#getOldValue()
.
public void changeListener(ValueChangeEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
}
이 <f:ajax listener>
메서드는 INVOKE_APPLICATION
단계 중에 호출됩니다 . 이때 제출 된 값은 이미 모델에서 업데이트되었습니다. 입력 구성 요소에 바인딩 된 빈 속성에 직접 액세스하여 가져올 수 있습니다 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 );