本文介绍了将实数值绑定到 Grails 域属性(由 Dojo 小部件发送的值)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 Dojo 1.9 和 Grails 2.3.9.

I am using Dojo 1.9 with Grails 2.3.9.

Dojo NumberTextBox 小部件 - 我在我的表单中使用 - 将固定格式(JavaScript 基本格式)的实数值(例如:12.56)设置到 HTML 表单输入字段中(但根据浏览器显示/编辑它们区域设置,因此用户始终可以看到格式正确的数字).

The Dojo NumberTextBox widget - that I use in my forms - sets real number values (e.g.: 12.56) in a fixed format (the JavaScript base format) into the HTML form input fields (but displays/edits them according to the browser locale, so the user always sees properly formatted numbers).

另一方面,Grails 期望输入字段根据浏览器区域设置进行格式化.

Grails on the other hand expects the input fields to be formatted according to the browser locale.

这会导致转换不匹配,结果是当浏览器区域设置不是英语时,Grails 会丢失小数位并将记录错误地保存到数据库中.

This results in a conversion mismatch and the effect is that Grails loses the decimal places when the browser locale is not English and saves the record incorrectly to the database.

我试图通过实现自定义 ValueConverter 并在应用程序上下文中注册它来覆盖 Grails 中的值转换.

I was trying to override the value conversion in Grails by implementing a custom ValueConverter and registering it in the application context.

浏览器发送的请求正确包含真实值(12.45")

The request sent by the browser contains the real value correctly ("12.45")

主要问题是我的转换器似乎根本没有使用.

The main problem is that my converter doesn't seem to be used at all.

如何注册它以覆盖默认的 Double 数据转换?

How do I register it to override the defaut Double data conversion?

转换器:

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)

My registration in the application context (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
}

推荐答案

我终于找到了解决方案.

I have finally found the solution.

主要问题是,转换器 bean 的命名是错误的.处理 double/Double 的两个转换器必须如下调用(在 applicationContext 中):

The primary problem was that, the naming of the converter beans was wrong. The two converters dealing with double/Double must be called the following (in the applicationContext):

  • "defaultGrailsdoubleConverter"(用于双精度)
  • "defaultGrailsjava.lang.DoubleConverter"(用于 Double)

这有点令人困惑,因为defaultDateConverter"以更简单的方式命名,我认为双转换器命名将与此一致.

This is slightly confusing since "defaultDateConverter" is named in a much more simple way and I thought the double converter naming will be consistent with that.

第二个问题是,如果您想从插件(而不是应用程序项目)覆盖这些,那么您必须从 YourGrailsPlugin.doWithSpring() 进行注册,因为 resources.groovy 不会与插件一起打包.如果您想从应用程序项目本身进行覆盖,那么将它们放在 resources.groovy 中就可以了.

Secondary problem is that if you want to override these from a plugin (as opposed to the application project), then you must do the registration from YourGrailsPlugin.doWithSpring() since resources.groovy will not be packaged with the plugin. If you want to do the override from the application project itself, then placing them in resources.groovy is fine.

您可能还想确保在 DataBinding 插件初始化后进行此注册,否则您的插件可能会先初始化,DataBinding 插件只会用默认值覆盖您的转换器注册.这可以通过宣布对来自 YourGrailsPlugin.groovy 的 DataBinding 插件的软依赖来实现:

You may also want to ensure that this registration happens AFTER the DataBinding plugin has been initialized, otherwise your plugin may be initialized first and the DataBinding plugin simply overwrites your converter registration with the defaults. This may be done by announcing a soft dependency on the DataBinding plugin from YourGrailsPlugin.groovy:

    def loadAfter = ['dataBinding']

这篇关于将实数值绑定到 Grails 域属性(由 Dojo 小部件发送的值)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 16:28