将实数值绑定到 Grails 域属性(Dojo 小部件发送的值)
Posted
技术标签:
【中文标题】将实数值绑定到 Grails 域属性(Dojo 小部件发送的值)【英文标题】:Binding real number values to Grails domain attributes (values sent by Dojo widgets) 【发布时间】:2014-08-08 02:00:05 【问题描述】:我将 Dojo 1.9 与 Grails 2.3.9 一起使用。
我在表单中使用的 Dojo NumberTextBox 小部件以固定格式(javascript 基本格式)将实数值(例如:12.56)设置到 html 表单输入字段中(但根据浏览器显示/编辑它们语言环境,因此用户总是能看到格式正确的数字)。
另一方面,Grails 期望输入字段根据浏览器区域设置进行格式化。
这会导致转换不匹配,结果是当浏览器区域设置不是英语时,Grails 会丢失小数位,并将记录错误地保存到数据库中。
我试图通过实现自定义 ValueConverter 并将其注册到应用程序上下文中来覆盖 Grails 中的值转换。
浏览器发送的请求正确包含真实值(“12.45”)
主要问题是我的转换器似乎根本没有使用。
如何注册它以覆盖默认的 Double 数据转换?
转换器:
package gefc.dojo.binding
import org.grails.databinding.converters.ValueConverter
import java.text.NumberFormat
/**
* Converter which allows that the doubles arrive
*/
class DojoDoubleValueConverter implements ValueConverter
NumberFormat fmt
DojoDoubleValueConverter()
// The number format sent by Dojo components
// English locale for the decimal separator
fmt = NumberFormat.getInstance(Locale.ENGLISH);
// no grouping
fmt.setGroupingUsed(false);
boolean canConvert(value) value instanceof String
def convert(value)
Number n = fmt.parse(value)
return n.doubleValue()
Class<?> getTargetType()
return Double.class
我在应用程序上下文中的注册 (resources.groovy)
beans =
// Dojo components send real values in a fixed, ISO format, while Grails
// expects them to be formatted according to client/browser locale
// So we need to override real value conversions
doubleConverter gefc.dojo.binding.DojoDoubleValueConverter
【问题讨论】:
可能相关***.com/questions/14877602/… 肯定是同样的问题。然而,似乎还没有解决方案(在 Grails 2.3.x 中)。问的人使用了旧的绑定框架,而我尝试使用 Grails 2.3 中引入的新绑定系统。 2.3.9 的手册并没有说要覆盖现有的转换器,只添加新的。 这可能会有所帮助:grails.1312388.n4.nabble.com/… 它基本上说您需要将转换器专门命名为“defaultDoubleConverter”以覆盖系统默认转换器。我会尽快测试并报告结果。 【参考方案1】:此问题已在 Grails 2.4+ 中修复
我在使用 Grails 2.3.8 的 Long 和 Integer 转换器时遇到了类似的问题。 Grails 使用 LocaleAwareNumberConverter 将字符串如“123abc”转换为“123”。 所以我定义了自己的转换器并覆盖了resources.groovy中的bean定义
beans =
"defaultGrailsjava.lang.LongConverter"(LongValueConverter)
"defaultGrailsjava.lang.IntegerConverter"(IntegerValueConverter)
class LongValueConverter implements ValueConverter
public LongValueConverter()
boolean canConvert(value)
value instanceof String
def convert(value)
return value?.toLong()
Class<?> getTargetType()
return Long.class
【讨论】:
【参考方案2】:我终于找到了解决办法。
主要问题是转换器 bean 的命名错误。处理 double/Double 的两个转换器必须如下调用(在 applicationContext 中):
“defaultGrailsdoubleConverter”(用于双精度) “defaultGrailsjava.lang.DoubleConverter”(用于双精度)这有点令人困惑,因为“defaultDateConverter”以更简单的方式命名,我认为双转换器命名将与此一致。
第二个问题是,如果您想从插件(而不是应用程序项目)覆盖这些,那么您必须从 YourGrailsPlugin.doWithSpring() 进行注册,因为 resources.groovy 不会与插件一起打包。如果您想从应用程序项目本身进行覆盖,那么将它们放在 resources.groovy 中就可以了。
您可能还想确保在初始化 DataBinding 插件之后进行此注册,否则您的插件可能会先初始化,而 DataBinding 插件只会用默认值覆盖您的转换器注册。这可以通过在 YourGrailsPlugin.groovy 中宣布对 DataBinding 插件的软依赖来完成:
def loadAfter = ['dataBinding']
【讨论】:
我无法让它为我工作 - 使用 Grails 2.3.11 并通过插件进行设置。我的双打仍然使用调用语言环境(例如“ES”)而不是“EN”来解释。我已将"defaultGrailsjava.lang.DoubleConverter"(EnglishValueConverter)
和defaultGrailsdoubleConverter(EnglishValueConverter)
添加到我的doWithSpring
中(我也尝试过完全限定的类名)。有什么想法吗?
抱歉,我终于搞定了。我绑定的 bean 使用了 Float(我第一次没有检查代码)。一旦我连接了一个“defaultGrailsjava.lang.FloatConverter”,它就起作用了。以上是关于将实数值绑定到 Grails 域属性(Dojo 小部件发送的值)的主要内容,如果未能解决你的问题,请参考以下文章