【问题标题】:Input fields hold previous values only if validation failed仅当验证失败时,输入字段才会保留以前的值
【发布时间】:2012-12-31 13:23:15
【问题描述】:

我想出了一个奇怪的问题。我试图隔离问题,所以以下是我的简化代码。

public class MyBean {

  private List<Data> dataList;
  Data selectedData;

  public MyBean() {
    dataList = new ArrayList<Data>();
    dataList.add(new Data("John", 16));
    dataList.add(new Data("William", 25));
  }

  public List<Data> getDataList() {
    return dataList;
  }

  public void edit(Data data) {
    selectedData = data;
  }
  public void newData() {
    selectedData = new Data(null, null);
  }

  public Data getSelectedData() {
    return selectedData;
  }

  public class Data {
    String name;
    Integer age;
    Data(String name, Integer age) {
      this.name = name;
      this.age = age;
    }
    public String getName() {
      return name;
    }
    public void setName(String name) {
      this.name = name;
    }
    public Integer getAge() {
      return age;
    }
    public void setAge(Integer age) {
      this.age = age;
    }
  }
}

xhtml:

<rich:modalPanel id="pop">
  <h:form>
    Name: <h:inputText value="#{myBean.selectedData.name}" required="true" id="txtName"/><br/>
    Age : <h:inputText value="#{myBean.selectedData.age}" required="true" id="txtAge"/>
    <a4j:commandButton value="Save"/>
    <a4j:commandButton value="Close" onclick="Richfaces.hideModalPanel('pop');return false;"/>
    <br/>
    <rich:message for="txtName"/><br/>
    <rich:message for="txtAge"/>
  </h:form>     
</rich:modalPanel>

<h:form>
  <rich:dataTable value="#{myBean.dataList}" var="data">
    <rich:column>#{data.name}</rich:column>
    <rich:column>
      <a4j:commandLink value="Edit" action="#{myBean.edit(data)}" reRender="pop" oncomplete="Richfaces.showModalPanel('pop')"/>
    </rich:column>
  </rich:dataTable>
  <a4j:commandButton value="New" action="#{myBean.newData()}" reRender="pop" oncomplete="Richfaces.showModalPanel('pop')"/>
</h:form>

这是错误的路径:

  1. 加载页面
  2. 点击第一行的“编辑”链接(弹出显示)
  3. 在弹出窗口中,清除“年龄”字段并单击“保存”。(显示必填信息)
  4. 点击取消(不填写“年龄”字段)
  5. 点击第二个链接。
  6. 现在它显示不相关的数据(以前的数据)。 - 这就是问题
  7. 即使我单击“新建”按钮,它也会显示不正确的数据。

仅当弹出窗口中的验证失败时才会发生这种情况。
有解决办法吗?

【问题讨论】:

  • 我知道这不会帮助您理解问题,但是您不应该相信控制器(服务器端)可以清除视图(JSF 页面)中的值使用纯 Javascript 完成(仅适用于 New &lt;a4j:commandButton&gt;)。
  • 感谢您对使用 javascript 的建议。我会试试看,一有时间就会通知你。
  • @LuiggiMendoza:我使用了 javascript 并取得了一些成功。但我的真实情况有点复杂,我无法在当前真实情况中使用javascript。但是,非常感谢您的提示,我希望添加 javascript 解决方法作为这个问题的答案,供其他人在有时间时使用。 :)

标签: jsf popup richfaces jsf-1.2 ajax4jsf


【解决方案1】:

这个问题在 JSF 2 中也得到了认可,并在以下答案中详细解释:How can I populate a text field using PrimeFaces AJAX after validation errors occur? 如果您使用的是 JSF 2,则可以为此使用 OmniFaces 的 ResetInputAjaxActionListener 或 PrimeFaces 的 &lt;p:resetInput&gt; or resetValues="true"

说到这一点,您需要在 EditableValueHolder 组件即将进行 ajax 渲染时清除它的状态,但它不包含在 ajax 执行中。要清除状态,在 JSF 2 中您可以使用便捷方法 resetValue(),但这在 JSF 1.2 中不可用,您需要调用 4 个单独的方法 setValue(null)setSubmittedValue(null)setLocalValueSet(false) , setValid(true) 清除状态。

要确定哪些组件将被 ajax 渲染,但不被 ajax 执行,在 JSF 2 中,您将为此使用 PartialViewContext 方法,但这在 JSF 1.2 中不可用,它还没有标准化的ajax呢。您需要摆弄 RichFaces 特定的 ajax API 才能弄清楚这一点。我无法从头顶上看出这一点,所以这是一个启动示例,假设您已经知道需要清除的组件。想象一下,弹出窗口中的表单有id="popForm",名称输入字段有id="nameInput",下面是如何在newData() 方法中清除它:

UIInput nameInput = (UIInput) context.getViewRoot().findComponent("popForm:nameInput");
nameInput.setValue(null);
nameInput.setSubmittedValue(null);
nameInput.setLocalValueSet(false);
nameInput.setValid(true);

【讨论】:

  • BalusC,非常感谢您的回答。它帮助我解决了我的问题。我根据您的示例更改了我的newData() 方法,并在我的edit(data) 方法中使用了nameInput.setValue(data.getName()); nameInput.setSubmittedValue(data.getName());nameInput.setLocalValueSet(false); nameInput.setValid(true);。这工作正常。您能否解释一下setLocalValueSet() 方法的作用。再次感谢。
  • 它在验证阶段提示 JSF 组件是否已经成功验证。如果组件尚未验证,isValid() 也会返回 true。仅当验证失败时,它才会返回 false。如果组件尚未验证,isLocalValueSet() 将返回 false。但如果验证成功,则设置本地值,isLocalValueSet() 将返回true
  • 嗨 BalusC。 ADF Faces 中有类似的东西吗?我不想调用 resetValue(),因为 Button 和 inputTexts 位于不同的区域,而且它们位于 af:iterator 中,我想要一个干净的解决方案。
【解决方案2】:

在取消操作上做一件事将所有弹出值设置为空。现在在您的下一次点击中将所有值设置为默认值。

或单击将所有以前的值设置为空。并在此之后设置所有相应的值。

【讨论】:

    【解决方案3】:

    我遇到了同样的问题。如果您使用 Primefaces,解决方案很简单,只需将 resetValues="true" 放在加载所选项目的 p:commandLink 或 p:commandButton 上。

    【讨论】:

    • 问题是关于 JSF1.2 和 RichFaces(RichFaces != PrimeFaces 并且具有此功能的 PrimeFaces 版本不支持 JSF 1.2)。此外它(几乎)已经在接受的答案中(现在是完全的)下次更好地编辑现有的很好解释的问题......但是感谢您提醒我们这个细节......(也许对答案的评论是一个选项到)。
    【解决方案4】:

    验证失败后,如果您希望与作为提交参数传递的输入数据保持相同,则将 value 属性 设置为您的表单 bean 名称,如下所述,即

    <input type="text" id="fname" path="fname" value="${myFormBean.fname}"/>
    

    【讨论】:

      猜你喜欢
      • 2011-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-02
      • 1970-01-01
      • 1970-01-01
      • 2020-03-13
      • 1970-01-01
      相关资源
      最近更新 更多