如何将JSF UIInput组件重置为其托管bean值

时间:2011-11-18 18:33:22

标签: java jsf primefaces

我想在验证失败后将JSF输入重置为原始托管bean值。

我在同一页面中有两个表单 - 第一个表单有一个commandLink来初始化第二个表单。第二种形式呈现为一个对话框,其可见性通过jQuery切换 - 为了本练习的目的,我可以在同一页面上用两个表单来说明。此外,当我在我的应用程序中使用PrimeFaces 2.2.x时,同样的行为也会出现在常规h:commandLink中。

我遇到的问题是:

  1. 点击第一个表单中的链接以初始化第二个表单
  2. 以第二种形式提交无效值
  3. 再次点击第一个表单中的链接以初始化第二个表单 - 仍然存在无效值和/或UIInput状态仍然无效。
  4. 例如 - 采取以下形式

    <h:form id="pageForm">
        <h:commandLink actionListener="#{testBean.initialize}">Initialize, no execute
            <f:ajax render=":dialogForm"/>
        </h:commandLink>
        <br/>
        <h:commandLink actionListener="#{testBean.initialize}">Initialize, execute=@this
            <f:ajax execute="@this" render=":dialogForm"/>
        </h:commandLink>
    
    </h:form>
    
    <h:form id="dialogForm">
        <h:messages/>
        String property - Valid: <h:outputText value="#{property.valid}"/>
        <br/>
        <h:inputText id="property" binding="#{property}" value="#{testBean.property}">
        <f:validateLength minimum="3"/>                         
        </h:inputText>
        <br />
        Int property - Valid: <h:outputText value="#{intValue.valid}"/>
        <h:inputText id="intValue" binding="#{intValue}" value="#{testBean.intValue}">
            <f:validateLongRange maximum="50" />                            
        </h:inputText>
        <br/>
    
        <h:commandLink actionListener="#{testBean.submit}">
            Submit
            <f:ajax render="@form" execute="@form"/>
        </h:commandLink>
    
        <h:commandLink actionListener="#{testBean.initialize}">Initialize, execute=@this
            <f:ajax execute="@this" render="@form"/>
        </h:commandLink>
    
    </h:form>
    

    Bean类:

    @ManagedBean
    @ViewScoped
    public class TestBean {
      private String property = "init";
      private Integer intValue = 33;
      // plus getters/setters
    
      public void submit() { ... }
      public void initialize() {
       intValue = 33;
       property = "init";   
      }
    
    }
    

    行为#1

    1. 点击pageForm
    2. 上的“初始化”链接
    3. 输入初始化为“init”,“33”
    4. 现在为“aa”,“99”
    5. 这两个字段提交无效内容
    6. 现在再次单击任何“初始化”链接(它们似乎都表现相同 - 无论是相同形式还是不同,或者我是否指定了execute =“@ this”都没有区别。)< / LI>

      结果=&gt; UIInput.isValid() = false,两个值都重置(“init”,“33”)。

      预期=&gt; valid = true(或者这不合理吗?)

      行为#2

      1. 点击pageForm
      2. 上的“初始化”链接
      3. 输入初始化为“init”,“33”
      4. 现在提交一些对文本字段无效但对int字段有效的内容(“aa”,“44”)
      5. 现在再次点击任何“初始化”链接
      6. 结果=&gt; “init”,valid = false; 44,有效=真

        预期=&gt; “init”,valid = true; 33,有效=真

        我也看过:

        JSF 2 - Bean Validation: validation failed -> empty values are replaced with last valid values from managed bean

        How can I populate a text field using PrimeFaces AJAX after validation errors occur?

        使用UIInputs 明确重置resetValue状态的建议确实有效,但我对它不满意。

        现在,我理解为什么isValid没有重置 - 我对JSF生命周期的理解是,一旦将值提交给组件,isValid就不会被重置,直到成功提交和验证组件并且更新模型值phase设置bean值。因此,在这种情况下,可能无法明确重置有效状态,因为我想使用#{foo.valid}进行条件CSS样式。

        但是,我不明白的是,成功验证的组件没有从bean重新初始化的原因。也许我对JSF生命周期的理解有点偏差?

        我理解规则在How can I populate a text field using PrimeFaces AJAX after validation errors occur?的答案中列出,因为它们与单个组件有关,但与整个表单无关 - 即,如果组件成功验证但验证整体失败会发生什么?

1 个答案:

答案 0 :(得分:0)

事实上,可能没有比在组件上显式调用resetValue更好的方法了。在我的例子中,所有对话框都在同一个大JSF视图树中,底层页面打开它们。因此,从JSF的角度来看,在我们离开视图之前,应该保留包含无效输入值的相同视图组件状态,因为它无法看到我们如何在客户端切换显示属性。

可能工作的唯一另一件事是,构成对话框的组件实际上没有在JSF视图树中呈现,除非它们可见。就我而言,它们总是被渲染,使用CSS来切换可见性。