当前位置: 首页 > 知识库问答 >
问题:

何时使用value ChangeListener或f: ajax侦听器?

崔宜修
2023-03-14

以下两段代码在listener位置上有什么区别?

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

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

共有2个答案

慎星纬
2023-03-14

对于第一个片段(ajax侦听器属性):

ajax标记的“listener”属性是一种方法,每当ajax函数在客户端发生时,服务器端就会调用它。例如,您可以使用该属性指定一个服务器端函数,以便在用户每次按键时调用该函数

但是第二个片段(valueChangeListener):

ValueChangeListener仅在提交表单时调用,而不是在更改输入值时调用

*你可能想看看这个方便的答案

崔博延
2023-03-14

value ChangeListener只有在提交表单并且提交的值与初始值不同时才会被调用。因此,只有触发超文本标记语言DOMchange事件时才不会调用它。如果您想在超文本标记语言DOMchange事件期间提交表单,那么您需要添加另一个

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

使用

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

另一个主要区别是value ChangeListener方法是在PROCESS_VALIDATIONS阶段结束时调用的。此时,提交的值还没有在模型中更新。因此,您无法通过访问绑定到输入组件的value的bean属性来获取它。您需要通过ValueChangeEvent#getNewValue()获取它。顺便说一句,旧值也可以通过ValueChangeEvent#getOldValue()获得。

public void changeListener(ValueChangeEvent event) {
    Object oldValue = event.getOldValue();
    Object newValue = event.getNewValue();
    // ...
}
private Object value; // +getter+setter.

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

此外,如果您需要根据提交的值更新另一个属性,那么当您使用value ChangeListener时它会失败,因为在随后的UPDATE_MODEL_VALUES阶段,提交的值可以覆盖更新的属性。这就是为什么您在旧的JSF 1. x应用程序/教程/资源中看到value ChangeListener在这种构造中与立即="true"FacesContext#renderACK()结合使用以防止这种情况发生。毕竟,使用value ChangeListener执行业务操作实际上一直是一种破解/解决方法。

概述:仅当需要截取实际值更改本身时,才使用valuechangeelistener。也就是说,你实际上对新旧价值都感兴趣(比如记录它们)。

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

使用

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

如果在执行业务操作时,您实际上也对旧值感兴趣,那么请退回到valueChangeListener,但将其排队到INVOKE_应用程序阶段。

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

 类似资料:
  • 问题内容: 以下两段代码之间的区别是什么? 和 问题答案: 的形式被提交时将只被调用 和 提交的值是从初始值不同。因此, 仅触发HTML DOM 事件时不会调用它。如果您想在HTML DOM 事件期间提交表单,则需要向输入组件添加另一个没有listener(!)的表单。它将导致仅处理当前组件的表单提交(如中所述)。 当使用代替时,默认情况下它将在HTML DOM 事件期间执行。在表示复选框或单选按

  • 问题内容: 我很好奇这两种执行ajax调用的方式有什么区别: 和 看来人们使用第一种方法的频率更高,但是第二种方法似乎也能正常工作… 问题答案: 第一种方法允许通过返回结果进行导航,而第二种则不能。如果客户端禁用了JS,第二种方法将不会调用任何内容,而第一种方法会正常降级。确实,第一种方法被更频繁地使用。 第二种方法是组件中没有属性的唯一方法,例如等等。

  • 问题内容: 在托管bean中使用适当的值正确生成了页面,但是这两个h:selectOneMenus中的ajax事件不起作用。不调用侦听器。标签内一定有错误,但我看不到。 托管Bean: 更新: 我发现了一些有趣的东西: 标签不工作,,,。在这种情况下,不会注意到属性中的错误值,但是属性的错误值会产生错误。 ,可以正常使用 问题答案: 该要求包含在HTML文件之中。它包含用于执行JSF ajax魔术

  • 问题内容: 有一种简单的方法可以在调用之前和之后调用JavaScript动作,例如,我想在后备bean中调用 之前 和 之后 调用JavaScript动作: 添加多个元素似乎不起作用(也许应该吗?!),例如 仅被调用。 问题答案: 使用属性。它必须指向一个回调函数引用(所以不要包括括号!): 实际的回调函数如下所示(JSF会自己提供参数):

  • 问题内容: 我有一个GPS跟踪器,可通过GPRS连接将数据连接并发送到已定义的公共服务器:端口。 我可以定义GPS设备的ip:port 我的问题是,我可以只在服务器中打开一个端口并侦听/保存使用PHP接收的数据吗? 谢谢。 问题答案: 编辑/更新2017年8月16日: 用户和库作者@Navarr评论说,他发布了该库的一个新的更新版本,我的原始答案中的代码基于该库。他的github上的新代码的链接在

  • 问题说明: