当使用valueChangeListener或f:ajax的听众? [英] When to use valueChangeListener or f:ajax listener?

查看:382
本文介绍了当使用valueChangeListener或f:ajax的听众?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是以下两件code之间的区别 - 与问候监听器布局

 < H:selectOneMenu用于...>
    < F:selectItems的... />
    < F:AJAX监听=#{bean.listener}/>
< / H:selectOneMenu用于>
 

 < H:selectOneMenu用于... valueChangeListener =#{bean.listener}>
    < F:selectItems的... />
< / H:selectOneMenu用于>
 

解决方案

valueChangeListener 当表单提交,然后才会被激活的提交的值是从初始值不同。它因此不调用时的只有的的HTML DOM 变更事件。如果您想在HTML DOM 变更在活动期间提交表单,那么你需要添加另一个< F:AJAX /> 未经听者(!)的输入部件。这会造成一种形式提交其只处理当前的组件(如执行=@这个)。

 < H:selectOneMenu用于值=#{bean.value}valueChangeListener =#{bean.changeListener}>
    < F:selectItems的... />
    < F:AJAX />
< / H:selectOneMenu用于>
 


在使用< F:AJAX收听GT; 而不是 valueChangeListener ,它会在默认情况下在HTML中执行DOM 变更事件了。在 UICommand 组件和输入组件重新presenting复选框或单选按钮,这将是默认的HTML DOM 点击事件而已。

 < H:selectOneMenu用于值=#{bean.value}>
    < F:selectItems的... />
    < F:AJAX监听=#{bean.ajaxListener}/>
< / H:selectOneMenu用于>
 


另一个主要区别是, PROCESS_VALIDATIONS 阶段结束时被调用的 valueChangeListener 方法。在那一刻,提交的值是没有在模型更新呢。所以,你不能得到它,只需访问其绑定到输入组件的 bean的属性。您需要通过来得到它ValueChangeEvent#的getNewValue()。旧值的方式也可以通过 ValueChangeEvent#getOldValue()

 公共无效的ChangeListener(ValueChangeEvent事件){
    对象的属性oldValue = event.getOldValue();
    对象为newValue = event.getNewValue();
    // ...
}
 


< F:AJAX收听GT;在调用方法INVOKE_APPLICATION 阶段。在那一刻,提交的值是已在模型更新。你可以得到它通过直接访问它绑定到输入组件的值的bean属性

 私有对象价值; // +吸气+二传手。

公共无效ajaxListener(AjaxBehaviorEvent事件){
    的System.out.println(值); //看,(新)值已经设置。
}
 


另外,如果你需要更新的另一个的基础上,提交的值属性,那么它会当你使用失败 valueChangeListener 作为更新属性的可以的被提交的值,在随后的 UPDATE_MODEL_VALUES 相覆盖。这正是为什么你的老JSF 1.x应用程序/教程/资源看,一个 valueChangeListener 就是在这样的结构是结合使用立即=真正的的FacesContext#的renderResponse()来prevent这种情况的发生。毕竟,使用 valueChangeListener 来执行业务操作实际上一直是黑客/解决方法。

总结:使用 valueChangeListener 只有当你需要拦截的实际价值变化本身。即你真正感兴趣的两个的旧的和新的值(例如,以记录他们)。

 公共无效的ChangeListener(ValueChangeEvent事件){
    changeLogger.log(event.getOldValue(),event.getNewValue());
}
 

使用了< F:AJAX收听GT; 仅当您需要执行的新变化值的业务操作。即你在的只有的新值(例如填充第二下拉)真正感兴趣。

 公共无效ajaxListener(AjaxBehaviorEvent事件){
    selectItemsOfSecondDropdown = populateItBasedOn(selectedValueOfFirstDropdown);
}
 

如果你其实也有兴趣在旧的价值,同时执行一个业务动作,然后回落到 valueChangeListener ,但排队的 INVOKE_APPLICATION 阶段。

 公共无效的ChangeListener(ValueChangeEvent事件){
    如果(event.getPhaseId()!= PhaseId.INVOKE_APPLICATION){
        event.setPhaseId(PhaseId.INVOKE_APPLICATION);
        event.queue();
        返回;
    }

    对象的属性oldValue = event.getOldValue();
    对象为newValue = event.getNewValue();
    的System.out.println(newValue.equals(值)); // 真正
    // ...
}
 

What's the difference between the following two pieces of code - with regards to listener placement?

<h:selectOneMenu ...>
    <f:selectItems ... />
    <f:ajax listener="#{bean.listener}" />
</h:selectOneMenu>

and

<h:selectOneMenu ... valueChangeListener="#{bean.listener}">
    <f:selectItems ... />
</h:selectOneMenu>

解决方案

The valueChangeListener will only be invoked when the form is submitted and the submitted value is different from the initial value. It's thus not invoked when only the HTML DOM change event is fired. If you would like to submit the form during the HTML DOM change event, then you'd need to add another <f:ajax/> without a listener(!) to the input component. It will cause a form submit which processes only the current component (as in execute="@this").

<h:selectOneMenu value="#{bean.value}" valueChangeListener="#{bean.changeListener}">
    <f:selectItems ... />
    <f:ajax />
</h:selectOneMenu>


When using <f:ajax listener> instead of valueChangeListener, it would by default executed during the HTML DOM change event already. Inside UICommand components and input components representing a checkbox or radiobutton, it would be by default executed during the HTML DOM click event only.

<h:selectOneMenu value="#{bean.value}">
    <f:selectItems ... />
    <f:ajax listener="#{bean.ajaxListener}" />
</h:selectOneMenu>


Another major difference is that the valueChangeListener method is invoked during the end of the PROCESS_VALIDATIONS phase. At that moment, the submitted value is not been updated in the model yet. So you cannot get it by just accessing the bean property which is bound to the input component's value. You need to get it by ValueChangeEvent#getNewValue(). The old value is by the way also available by ValueChangeEvent#getOldValue().

public void changeListener(ValueChangeEvent event) {
    Object oldValue = event.getOldValue();
    Object newValue = event.getNewValue();
    // ...
}


The <f:ajax listener> method is invoked during INVOKE_APPLICATION phase. At that moment, the submitted value is already been updated in the model. You can just get it by directly accessing the bean property which is bound to the input component's value.

private Object value; // +getter+setter.

public void ajaxListener(AjaxBehaviorEvent event) {
    System.out.println(value); // Look, (new) value is already set.
}


Also, if you would need to update another property based on the submitted value, then it would fail when you're using valueChangeListener as the updated property can be overridden by the submitted value during the subsequent UPDATE_MODEL_VALUES phase. That's exactly why you see in old JSF 1.x applications/tutorials/resources that a valueChangeListener is in such construct been used in combination with immediate="true" and FacesContext#renderResponse() to prevent that from happening. After all, using the valueChangeListener to execute business actions has actually always been a hack/workaround.

Summarized: Use the valueChangeListener only if you need to intercept on the actual value change itself. I.e. you're actually interested in both the old and the new value (e.g. to log them).

public void changeListener(ValueChangeEvent event) {
    changeLogger.log(event.getOldValue(), event.getNewValue());
}

Use the <f:ajax listener> only if you need to execute a business action on the newly changed value. I.e. you're actually interested in only the new value (e.g. to populate a second dropdown).

public void ajaxListener(AjaxBehaviorEvent event) {
    selectItemsOfSecondDropdown = populateItBasedOn(selectedValueOfFirstDropdown);
}

If you're actually also interested in the old value while executing a business action, then fall back to valueChangeListener, but queue it to the INVOKE_APPLICATION phase.

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
    // ...
}

这篇关于当使用valueChangeListener或f:ajax的听众?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆