我有一个JSF 2.2应用程序,用户必须输入BigDecimal
值<h:inputText>
.对于这样的输入字段,a valueChangeListener
被配置为在输入变化时被调用.这是XHTML代码:
<h:form id="theForm">
<h:inputText id="bd" value="#{bean.bd}"
valueChangeListener="#{bean.bdChangedListener()}"/>
<h:commandButton id="submit" value="Submit" />
</h:form>
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,这样做很好.bdChangedListener()
当值改变并按下提交按钮时,将调用该方法.该值已正确提交给模型.
但是,如果我进入1.1
并改变它1.10
,新的值被提交到模型,但valueChangeListener
在从来没有所谓!Debuging表明,其原因在于javax.faces.component.UIInput#compareValues()
.这种方法的JavaDoc
说:
如果新值与先前值不同,则返回true.首先通过将值传递给参数previous之前的equals方法来比较这两个值.如果该方法返回true,则返回true.如果该方法返回false,并且两个参数都实现java.lang.Comparable,则通过将值传递给参数previous之前的compareTo方法来比较这两个值.如果此方法返回0,则返回true,否则返回false.
所以在我看来,这是故意的.但为什么?
用户输入已更改,并且存在应用程序,其中a的比例BigDecimal
是相关的.所以JSF不应该忽略改变的输入,而是通知我!它使用新值更新模型,为什么它会跳过valueChangeListener-method?
我怎样才能避免这种行为并以干净的方式得到通知?(我知道我可以挂进制定者,但这不是我所谓的干净方式!)
有任何想法吗?
除了上面我想提到的,我已经读过像BigDecimal equals()和compareTo()这样的问题.我确实理解为什么BigDecimal equals()
和compareTo()
他们的行为一样,我说它是正确的.BigDecimal的行为不是问题,UIInput.compareValues()
而是问题.
此外,转换器(如评论或已删除的答案中所示)将无法保存我的一天.用户输入已正确转换,我需要BidDecimal,包括我的应用程序中的确切比例.任何返回BigDecimal的转换器都不会改变观察到的行为.
围绕BigDecimal的包装类可能会解决我的问题,但不是我认为的干净解决方案.我真的想知道为什么UIInput的行为方式.
它确实按照指定的方式运行。就是这样。您已经非常正确地确定了根本原因javax.faces.component.UIInput#compareValues()
。解决方案是让它跳过额外的Comparable#compareTo()
检查。
您最好的选择是相应地扩展HtmlInputText
并覆盖compareValues()
。
@FacesComponent(createTag=true)
public class InputBigDecimal extends HtmlInputText {
@Override
protected boolean compareValues(Object previous, Object value) {
return !Objects.equals(previous, value);
}
}
Run Code Online (Sandbox Code Playgroud)
然后只需替换<h:inputText>
为<x:inputBigDecimal>
如下所示。
<... xmlns:x="http://xmlns.jcp.org/jsf/component">
...
<h:form id="theForm">
<x:inputBigDecimal id="bd" value="#{bean.bd}"
valueChangeListener="#{bean.bdChangedListener()}" />
<h:commandButton id="submit" value="Submit" />
</h:form>
Run Code Online (Sandbox Code Playgroud)
注意:代码按原样完整。由于 JSF 2.2 的createTag=true
. 您只会错过 IDE 的 XML 智能感知,但这是一个不同的问题。
归档时间: |
|
查看次数: |
287 次 |
最近记录: |