【问题标题】:Bean value not updated before ajax event listener is called在调用 ajax 事件侦听器之前未更新 Bean 值
【发布时间】:2015-07-11 05:20:03
【问题描述】:

我在实现一个 ajax 监听器事件时遇到了一些麻烦,该事件检测表单上的日期何时更改。我有一个数据表,在其中一个列中我有一个<ace:dateTimeEntry>,它包含一个存储在 bean 中的开始日期字段。 (注意:alloy 是用于数据表的变量的名称)。

<ace:column headerText="Start Date" rendered="#{not alliance.deletePending}">
    <ace:dateTimeEntry id="startDateField" value="#{alliance.allianceStartDate}" pattern="dd/MMM/yyyy" renderAsPopup="true" effect="fadeIn">
        <ace:ajax execute="@this" render="@this" event="dateSelect" listener="#{allianceViewBean.changeAllianceActiveIndicator}"/>
        <ace:ajax execute="@this" render="@this" event="dateTextChange" listener="#{allianceViewBean.changeAllianceActiveIndicator}"/>
    </ace:dateTimeEntry>
</ace:column>

我正在使用一个标签,它调用了 bean 中的侦听器方法

#{allianceViewBean.changeAllianceActiveIndicator}

这是改变bean值的方法:

public void changeAllianceActiveIndicator(AjaxBehaviorEvent event) {
    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

    Calendar c = Calendar.getInstance();
    c.setTimeZone(TimeZone.getTimeZone("UTC"));

    java.util.Date currentDate = c.getTime();

    for (AllianceBean bean : carrierAllianceDetails) {
        if ((bean.getAllianceStartDate().compareTo(currentDate) < 0)
            && (bean.getAllianceEndDate().compareTo(currentDate) > 0)) {
            bean.setActive(true);
        } else {
            bean.setActive(false);
        }
    }
}

但是,当我调试此方法时会发生错误。侦听器正确到达该方法,但 bean 中的开始日期值不是更新值,它仍然引用更改前的旧值。如果我在表单上输入一个新值,bean 中的值始终是指先前输入的日期值。方法中的逻辑是正确的,但被检查的值不正确。

我不确定如何确保侦听器方法从表单中获取最新值。

谢谢

【问题讨论】:

  • 看起来“dateTextChange”监听器在输入日期时工作。但是,当从 中选择日期时,“dateSelect”监听器不会更新 bean 值。
  • 基本上我想在ajax监听之前设置bean属性。

标签: ajax jsf icefaces


【解决方案1】:

这是由于您处于生命周期阶段。检查此事件进入的生命周期阶段。如果它在 UPDATE_MODEL_VALUES 阶段之前(例如,在 PROCESS_VALIDATIONS 阶段),那么您的 bean 值根本还没有更新。在这种情况下,我建议在事件中将 phaseId 设置为 INVOKE_APPLICATION,将其排队并返回方法:

public void changeAllianceActiveIndicator(AjaxBehaviorEvent event) {
    if (!event.getPhaseId().equals(PhaseId.INVOKE_APPLICATION) {
        event.setPhaseId(PhaseId.INVOKE_APPLICATION);
        event.queue();
        return;
    }

    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));

    Calendar c = Calendar.getInstance();
    c.setTimeZone(TimeZone.getTimeZone("UTC"));

    java.util.Date currentDate = c.getTime();

    for (AllianceBean bean : carrierAllianceDetails) {
        if ((bean.getAllianceStartDate().compareTo(currentDate) < 0)
            && (bean.getAllianceEndDate().compareTo(currentDate) > 0)) {
            bean.setActive(true);
        } else {
            bean.setActive(false);
        }
    }
}

除此之外,您方法的代码也不理想。设置默认时区已经过时了——整个日历块也是如此。你可以这样做

Date currentDate = new Date();

我还建议将 bean 上设置的日期转换为服务器时区的日期 - 否则您是在比较苹果和橘子。

【讨论】:

  • if (!event.getPhaseId().equals(PhaseId.INVOKE_APPLICATION) { 缺少右括号 :)
猜你喜欢
  • 2013-06-27
  • 1970-01-01
  • 1970-01-01
  • 2020-02-12
  • 1970-01-01
  • 2017-09-24
  • 2011-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多