何时使用valueChangeListener或f:ajax listener?
下面两段代码有什么区别 – 关于监听器放置?
<h:selectOneMenu ...> <f:selectItems ... /> <f:ajax listener="#{bean.listener}" /> </h:selectOneMenu> 和 <h:selectOneMenu ... valueChangeListener="#{bean.listener}"> <f:selectItems ... /> </h:selectOneMenu>
仅当提交表单并且提交的值与初始值不同时,才会调用valueChangeListener。因此,只有在触发HTML DOM更改事件时,才会调用它。如果您想在HTML DOM更改事件期间提交表单,则需要添加另一个< f:ajax />没有监听器(!)到输入组件。它将导致一个表单提交,只处理当前组件(如execute =“@ this”)。
<h:selectOneMenu value="#{bean.value}" valueChangeListener="#{bean.changeListener}"> <f:selectItems ... /> <f:ajax /> </h:selectOneMenu> 当使用< f:ajax listener>而不是valueChangeListener,它将默认在HTML DOM更改事件期间已执行。在UICommand组件和表示复选框或单选按钮的输入组件的内部,它将默认在HTML DOM点击事件期间执行。 <h:selectOneMenu value="#{bean.value}"> <f:selectItems ... /> <f:ajax listener="#{bean.ajaxListener}" /> </h:selectOneMenu> 另一个主要区别是在PROCESS_VALIDATIONS阶段结束时调用valueChangeListener方法。此时,提交的值尚未在模型中更新。所以你不能通过访问绑定到输入组件的值的bean属性来获得它。你需要通过ValueChangeEvent#getNewValue()获取它。旧的值也是可用的ValueChangeEvent#getOldValue()。 public void changeListener(ValueChangeEvent event) { Object oldValue = event.getOldValue(); Object newValue = event.getNewValue(); // ... } < f:ajax listener>方法在INVOKE_APPLICATION阶段被调用。此时,已提交的值已在模型中更新。你可以通过直接访问绑定到输入组件的值的bean属性来获得它。 private Object value; // +getter+setter. public void ajaxListener(AjaxBehaviorEvent event) { System.out.println(value); // Look,(new) value is already set. } 另外,如果您需要基于提交的值更新另一个属性,那么当您使用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)); // true // ... } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |