14

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

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. 即使我单击“新建”按钮,它也会显示不正确的数据。

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

4

4 回答 4

34

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

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

要确定哪些组件要进行 ajax 渲染,但不进行 ajax 执行,在 JSF 2 中您可能会PartialViewContext为此使用方法,但在尚未标准化 ajax 的 JSF 1.2 中不可用。您需要摆弄 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);
于 2013-01-17T13:34:02.817 回答
1

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

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

于 2013-01-17T09:57:20.360 回答
1

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

于 2017-05-23T00:11:02.523 回答
-2

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

<input type="text" id="fname" path="fname" value="${myFormBean.fname}"/>
于 2020-03-29T14:29:16.173 回答