我有一个JSF2.2应用程序,用户必须在
<h:form id="theForm">
<h:inputText id="bd" value="#{bean.bd}"
valueChangeListener="#{bean.bdChangedListener()}"/>
<h:commandButton id="submit" value="Submit" />
</h:form>
这在大多数情况下都很有效。当值更改并按下提交按钮时,将调用
bdChangedListener()
方法。该值已正确提交到模型。
但是,如果我输入
1.1
并将其更改为1.10
,则新值将提交给模型,但从未调用值更改侦听器
!调试表明,原因在于javax。面孔。组成部分UIInput#compareValues()
。此方法的JavaDoc表示:
如果新值与以前的值不同,则返回true。首先通过将value传递给前一个参数上的equals方法来比较这两个值。如果该方法返回true,则返回true。如果该方法返回false,并且两个参数都实现java。lang.Compariable,通过将值传递给前一个参数上的compareTo方法来比较这两个值。如果此方法返回0,则返回true,否则返回false。
所以在我看来,这是故意的。但是为什么呢?
用户输入发生了变化,有些应用程序与
bigdecimic
的比例相关。所以JSF不应该忽略更改的输入,而是通知我!它用新值更新模型,为什么要跳过valueChangeListener方法?
我怎样才能避免这种行为,并以干净的方式得到通知?(我知道我可以打二传,但这不是我所说的干净的方式!)
有什么想法吗?
除了上面我想提到的,我已经读了像BigDecimal equals()和compareTo()这样的问题。我确实理解为什么BigDecimal的
才是问题所在。equals()
和compareTo()
表现得像他们一样,我认为这是正确的。BigDecimal的行为不是问题所在,UIInput.compare值()
此外,转换器(如评论中建议的或已删除的答案)也无法保存我的一天。用户输入正确转换,我需要BidDecimal,包括我的应用程序中的精确比例。任何返回BigDecimal的转换器都不会改变观察到的行为。
围绕BigDecimal的包装类可能会解决我的问题,但不是我认为的干净的解决方案。我真的很想知道为什么UIInput会这样。
BalusC的回答描述了一种通用的方法,在不改变应用程序行为的情况下以一种干净的方式解决问题。可能的解决方法是使用AJAX-listener
,而不是value eChangeListener
:
<h:form id="theForm">
<h:inputText id="bd" value="#{bean.bd}">
<f:ajax listener="#{bean.ajaxListener}"/>
</h:inputText>
<h:commandButton id="submit" value="Submit" />
</h:form>
侦听器
方法必须具有不同的签名:
public void ajaxListener(AjaxBehaviorEvent event)
{
// Do whatever you like here.
// The new value is already in the model.
}
请注意,只要触发DOM更改事件(而不是按下sumbit按钮),就会调用AJAX侦听器,并且不会像valueChangeListener
那样检查实际值是否更改。
关于这两种方法的差异,可以在BalusC关于何时使用valueChangeListener或f:ajax listener?的出色回答中找到详细信息?。
它的行为确实符合规定。事实就是这样。您已经非常正确地确定了javax的根本原因。面孔。组成部分UIInput#compareValues()
。解决方案是让它跳过额外的Comparable#compareTo()
检查。
最好的办法是扩展HtmlInputText
并相应地覆盖compareVales()
。
@FacesComponent(createTag=true)
public class InputBigDecimal extends HtmlInputText {
@Override
protected boolean compareValues(Object previous, Object value) {
return !Objects.equals(previous, value);
}
}
然后只需更换
<... 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>
注意:代码是完整的。由于JSF 2.2的
createTag=true
,不需要额外的XML配置文件。在这方面,您只会错过IDE的XML智能,但这是一个不同的问题。
问题内容: 是否可以在sql中执行更新语句,但仅在更新不同时才执行更新? 例如 如果在数据库中, 不应 执行任何类型的更新 但是,如果 这 应该 执行更新。 问题答案: 使用更新前触发器可以做到这一点。在此触发器中,您可以将旧值与新值进行比较,并在新值不变的情况下取消更新。但这将导致呼叫者网站上的错误。 我不知道为什么要这样做,但是这里有几种可能性: 性能:这里没有性能提升,因为更新不仅需要找到正
以下是我需要更改的一些值: 如果第一列是2= 如果第一列是8= 如果第一列是16= 然而,这个命令并不方便,因为它改变了缩进,并且带有8的行似乎不适合: 输出: 您将如何更正更通用的内容(这意味着即使特定行的缩进不同,它也可以工作),并且不会改变原始文件的缩进?
问题内容: 我有一个字段的最小值取决于另一字段中给定的输入的要求。 此输入用于验证另一个字段 但这不能按预期工作..如果我以后更改“ minval”,则输入不会得到重新验证。 我已经尝试根据一些解决方案中的建议从JS设置min的初始值,但这也无济于事… 链接器 问题答案: 使用ng-min / ng-max指令
我想使用JavaFX ListView控件显示一个人员列表(在POJOS中编码,包含一个name和surname属性)。我创建了ListView,并将persons列表添加为ObservableList。如果我在ObservableList中删除或添加一个新人,那么一切都可以正常工作,但是POJO中的更改不会触发ListView的更新。我必须从ObservableList中移除和添加修改后的POJ
SQL架构: 我需要这样显示我的结果: 结果显示表SNMASTER的前5行 然后查看表事务,并在有OPERATION_ID时写入1
我正在做一个数据密集的角度项目,在这个项目中,我有一个ng重复,其中许多值每秒更新一次。如果一个值为空,它现在会更新DOM以显示一个空值;这是正确的行为。 需要的解决方案 我想要的是一个过滤器或表达式,当新值为空或NULL时,它不会更新DOM中的值。我相信他们称之为“锁定数据”。 可能的解决方案 我用$watch找到了几个可能的解决方案,但我相信它们不适合ng重复,或者至少效率不高:angular