Dan*_*jel 83 ajax jsf listener valuechangelistener jsf-2
以下两段代码之间有什么区别 - 关于listener放置?
<h:selectOneMenu ...>
<f:selectItems ... />
<f:ajax listener="#{bean.listener}" />
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)
和
<h:selectOneMenu ... valueChangeListener="#{bean.listener}">
<f:selectItems ... />
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)
Bal*_*usC 178
的valueChangeListener形式被提交时将只被调用和提交的值是从初始值不同.因此,仅change触发HTML DOM 事件时不会调用它.如果您想在HTML DOM change事件期间提交表单,那么您需要<f:ajax/>在输入组件中添加另一个没有监听器(!)的表单.它将导致表单提交仅处理当前组件(如execute="@this").
<h:selectOneMenu value="#{bean.value}" valueChangeListener="#{bean.changeListener}">
<f:selectItems ... />
<f:ajax />
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)
当使用<f:ajax listener>而不是valueChangeListener,它将默认在HTML DOM change事件期间执行.UICommand表示复选框或单选按钮的内部组件和输入组件,默认情况click下仅在HTML DOM 事件期间执行.
<h:selectOneMenu value="#{bean.value}">
<f:selectItems ... />
<f:ajax listener="#{bean.ajaxListener}" />
</h:selectOneMenu>
Run Code Online (Sandbox Code Playgroud)
另一个主要区别是该valueChangeListener方法在PROCESS_VALIDATIONS阶段结束时被调用.此时,尚未在模型中更新提交的值.所以你不能通过访问绑定到输入组件的bean属性来获取它value.你需要得到它ValueChangeEvent#getNewValue().顺便提一下,旧的价值也是可用的ValueChangeEvent#getOldValue().
public void changeListener(ValueChangeEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
// ...
}
Run Code Online (Sandbox Code Playgroud)
<f:ajax listener>在INVOKE_APPLICATION阶段期间调用该方法.此时,提交的值已在模型中更新.您可以通过直接访问绑定到输入组件的bean属性来获取它value.
private Object value; // +getter+setter.
public void ajaxListener(AjaxBehaviorEvent event) {
System.out.println(value); // Look, (new) value is already set.
}
Run Code Online (Sandbox Code Playgroud)
此外,如果您需要根据提交的值更新另一个属性,那么在您使用时它将失败,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());
}
Run Code Online (Sandbox Code Playgroud)
使用<f:ajax listener>,如果你需要执行的新改变价值的商业行为而已.即你实际上只对新值感兴趣(例如填充第二个下拉列表).
public void ajaxListener(AjaxBehaviorEvent event) {
selectItemsOfSecondDropdown = populateItBasedOn(selectedValueOfFirstDropdown);
}
Run Code Online (Sandbox Code Playgroud)
如果您在执行业务操作时实际上也对旧值感兴趣,那么请回退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)); // true
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
93154 次 |
| 最近记录: |