2011-09-05 32 views
2

更新:现在更新一次。我想我以前的分析是错误的,因为我现在已经能够为此创建一个例子。它似乎与复合组件和insertChildren标记有关。cc:insertChildren内的UIInput值在验证失败后不会重新显示

这是我的facelet:

<?xml version='1.0' encoding='UTF-8' ?> 
<html xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:h="http://java.sun.com/jsf/html" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:form="http://java.sun.com/jsf/composite/composite/form" 
    xmlns:ui="http://java.sun.com/jsf/facelets"> 

<h:head></h:head> 

<h:body> 
     <h:form> 
     <form:workspace> 

      <h:inputText id="email" value="#{user.email}" size="45" 
       required="true" requiredMessage="Required"> 
       <f:validateRegex pattern="([^[email protected]]+)(\.[^[email protected]]+)*@([^[email protected]]+\.)+([^[email protected]]+)" /> 
      </h:inputText> 
      <h:message for="email" /> 
      <br /> 
      <h:commandButton action="#{user.update}" value="Update"/> 

     </form:workspace> 
     </h:form> 
</h:body> 
</html> 

形式:工作空间复合分量被定义为如下:

<?xml version='1.0' encoding='UTF-8' ?> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:ui="http://java.sun.com/jsf/facelets" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:c="http://java.sun.com/jsp/jstl/core" 
     xmlns:cc="http://java.sun.com/jsf/composite"> 

<cc:interface> 
</cc:interface> 

<cc:implementation> 
    <cc:insertChildren/> 
</cc:implementation> 
</html> 

#{user}变量指的是微不足道的豆只需字段称为电子邮件和getter和setter。更新方法什么都不做。

我得到的行为如下所述。当我输入一个无效值时,它将恢复到它存储在bean中的值。如果我通过form:workspace组件删除包装,它就像我期望的那样工作 - 值不会被还原。 JSF的错误?


我有一个JSF窗体,有许多输入组件。其中一些有验证者附在他们身上。例如,一个简单的是电子邮件地址,这是强制性的:

<h:inputText id="email" value="#{profile.user.email}" size="45" 
    required="true" requiredMessage="Required"> 

现在,我们已经收到了这是无效的领域应该保持提交的值在他们的要求,所以用户不必为简单的拼写错误重新输入大量文本。这对我来说似乎很合理,我甚至认为这是验证的默认行为。但它似乎并不是 - 价值恢复到之前的水平(当它仍然有效时)。

问题是,我什至不能找到什么行为应该是一个参考。我在某处读到它是验证后显示的UIInput的本地值。检查UIInput的代码告诉我,如果验证失败,则故意不设置本地值。但是这似乎并不是全部真相,因为所有输入字段都被还原 - 不仅仅是验证失败的字段!所以看起来更像是它再次从模型中获取值。

无论如何,有没有办法绕过这种行为?

我正在使用JSF 2.0.4-b09。我觉得我失去了一些明显的东西。

编辑:我将电子邮件验证器更改为下面发布的正则表达式BalusC,并且我仍然得到相同的行为。我张贴了说明问题的图片。图像的上半部分显示了表单的初始状态。然后中间的部分显示我改变了字段“名字”,“姓氏”和“电子邮件”。底部显示了我点击保存按钮后的结果。如您所见,电子邮件字段已恢复。不仅如此,名字和姓氏字段也被还原。

Problem illustrated in three steps.

+0

可能的重复:http://stackoverflow.com/questions/1953350/jsf-validation-error-lost-value –

+0

@Zenzen:我没有重复那个,但它似乎专门针对h:inputHidden。 – waxwing

回答

4

有一些混乱回事。当提交的值为时为空(即,用户移除了初始值或者什么都不输入),该值仅恢复为初始值。我不确定如何重新键入整个文本的问题与此相关,因为实际上没有输入任何内容。

当提交的值为空或null时,JSF将重新显示模型值,否则它将重新显示提交的值,完全如您所期望的那样。这是在JSF规范中指定的。要亲自查看,请添加例如

<f:validateRegex pattern="([^[email protected]]+)(\\.[^[email protected]]+)*@([^[email protected]]+\\.)+([^[email protected]]+)" /> 

到电子邮件输入字段。您会看到,如果电子邮件格式无效,则会保留任何非空(!)提交的值。


更新:根据您的更新事实证明,您的输入组件实际上是被<cc:insertChildren>渲染。这种行为确实是莫哈拉的一个错误。见issue 1991。如问题单中所述,解决方法是将<cc:insertChildren />置于<h:panelGroup><ui:fragment>之内。

<cc:implementation> 
    <ui:fragment>   
     <cc:insertChildren/>   
    </ui:fragment> 
</cc:implementation> 

MyFaces 2.1.1没有这个bug,它在那里工作正常。

+0

我很确定空值也被保留(required =“true”验证)。只有当提交的值为空时,才会重新读取模型值。 – Andrey

+0

然后,我的配置确实有问题。我添加了一个截图来说明问题。我用你的正则表达式验证器得到相同的行为/问题。往上看。 – waxwing

+0

@Andrey:啊对了,我有一个'javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL'上下文参数设置为'true'。 @Waxwing:有趣的是,你使用ajax吗?什么组件库?也许它是重新渲染零件的过度热情?你能展示最低的视图代码吗? – BalusC

0

也许你有一些代码,做panelGroup里面输入组件明确提交值(例如panelGroup具有特定id,或代码做更多的通用分析查找用于panelGroups内部形式)。

试图通过项目源代码做全文搜索setSubmittedValue电话。

+0

搜索返回无匹配项。我们尝试尽可能少地直接与JSF组件树进行交互。更具体地说:我可以在模型类中放置一个断点,并实际看到它在渲染阶段重新读取模型中的值。 – waxwing