如何更改 GRAILS GSP fieldValue 格式化整数的方式?

How can I change the way GRAILS GSP fieldValue formats Integers?

提问人:Simon 提问时间:1/21/2010 最后编辑:Simon 更新时间:3/23/2016 访问量:15917

问:

我的域对象中有一个字段,我将其定义为整数...

Integer minPrice

然后,我在 GSP 页面中访问它,如下所示:

${fieldValue(bean: myBean, field: 'minPrice')}

我在 HTML 中得到的是......

100,000

它不是整数,而是字符串。更糟糕的是,它是特定语言环境中的格式化字符串。

这是一个问题,因为我在 HTML FORM 上有一个 SELECT 控件,该控件具有 minPrice 的(非序数)值范围,我想将其作为整数存储在我的域对象中,并且我不想将索引存储到我必须反复来回映射的某个值数组, 我想要价值本身。

我的选择控件如下所示...

<g:select name="minPrice" 
value="${fieldValue(bean: personInstance, field: 'minPrice')}"  
onchange="setDirty()"
noSelection='${['0':'Select a number...']}'
from="${[
    ['name':'100,000', 'id':100000],
    ['name':'200,000', 'id':200000],
    ['name':'300,000', 'id':300000]
    ]}"
optionKey="id" optionValue="name"
/>

当我从 SELECT 字段获取值以回发到服务器时,它正确地具有一个 Integer 值,我保留了该值。但是,返回行程永远不会在下拉列表中预先选择正确的行,因为值是逗号分隔的 String。

这在我的代码中的其他地方适用于逗号格式不起作用的小数字,并且进出 SELECT 是成功的。但是值 >999 不起作用。

文档说:“此标记将检查作为数据绑定主题的 bean,并从数据绑定期间填充的 bean 的 errors 对象中包含的原始提交值或从 Bean 属性的值中获取字段的值。一旦获得该值,它将自动进行 HTML 编码。

这是我想避免的最后一点,因为它似乎格式化了整数。那么,我需要了解 Grails/GSP 的哪些魔法,才能将我的 Integer 作为整数呈现到我的 SELECT 中并预先选择正确的行?

编辑:根据下面的答案,我尝试了一些进一步的东西,到目前为止,结果非常令人失望......

如果我把标签放在我的标签中,我会在浏览器中以文本形式获得页面代码。<gformatNumber/><g:select/>

<g:select name="minPrice" 
value='<g:formatNumber number="${fieldValue(bean: personInstance, field: 'minPrice')}" format="#" />'
onchange="setDirty()"
noSelection='${['0':'Select a number...']}'
from="${[
['name':'100,000', 'id':100000],
['name':'200,000', 'id':200000],
['name':'300,000', 'id':300000],
]}"
optionKey="id" optionValue="name"
/>

在我的整数值 100000 上使用 GSP 的数字格式标签,如下所示......

var x = <g:formatNumber number="${fieldValue(bean: personInstance, field: 'minPrice')}" format="#" />;

给。请记住,回馈,所以这并不奇怪。100fieldValue100,000

如果我像这样使用 jsp taglib...

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
var y = <fmt:formatNumber value="${fieldValue(bean: personInstance, field: 'minPrice')}" pattern=".00"/>;

我从页面编译器收到错误。Cannot format given Object as a Number

我想我有一个更广泛的担忧,如果由于 fieldValue 指令的默认(和不可配置)行为而大于 999,我似乎无法将 Integer 值作为真正的整数放入我的代码中。但是,我无法在 SELECT 控件中预先选择 Integer 值的具体问题不会消失。目前我有点不知所措。

有人有进一步的想法吗?

Grails GSP

评论


答:

6赞 Brandon 1/21/2010 #1

我认为您至少有两种可能的解决方案。

一种是按照文档中的描述使用 JSTL taglib。

另一种更酷的方法是使用圣杯附带的“formatNumber”标签 - 也在文档中。

出于您的目的,该标记的使用可能如下所示:

<g:formatNumber number="${fieldValue(bean: myBean, field: 'minPrice')}" format="######" />

评论

0赞 Simon 1/22/2010
我无法使这些解决方案中的任何一个起作用......请参阅上面的编辑。回想起来,很明显,如果这是普通的 Java,我不需要数字格式化程序,我需要 Integer.parseInt() 将结果从 fieldValue 返回为正确的类型。这不可能这么难......我做错了什么。
0赞 Simon 1/22/2010 #2

我有一个解决方案/回合......答案似乎是,“什么都不做”。

我没有尝试将字符串化的数字解析回整数,而是将其保留为格式化字符串以进行选择。这意味着我必须按如下方式更改我的价值观:from

<g:select name="minPrice" 
value="${fieldValue(bean: personInstance, field: 'minPrice')}"  
onchange="setDirty()"
noSelection='${['0':'Select a number...']}'
from="${[
    ['name':'100,000', 'id':'100,000'],
    ['name':'200,000', 'id':'200,000'],
    ['name':'300,000', 'id':'300,000']
    ]}"
optionKey="id" optionValue="name"
/>

当然,当我回发到服务器时,发送的值是“100,000”作为转义字符串。我意识到,Grails、Spring、Hibernate 或堆栈中的某些东西会在持久化之前将 String 强制回正确的 Integer 类型。

这对于我的目的来说效果很好,但是由于语言环境问题,我认为这基本上是一个解决方法,而不是解决方案。如果我的千位分隔符是“.”,而我的小数点分隔符是“,”,这是欧洲大部分地区的情况,那么我的代码将不起作用。

3赞 Victor Sergienko 12/14/2010 #3

最好使用自定义 PropertyEditor,这样就不会在每次输出值时都为标记而烦恼。 比如,在 resources.groovy 中声明一个 bean:formatNumber

myOwnCustomEditorRegistrar(CustomEditorRegistrar)

并创建您的类:

class CustomEditorRegistrar implements PropertyEditorRegistrar {
    void registerCustomEditors(PropertyEditorRegistry registry) {
        registry.registerCustomEditor(BigDecimal.class, new MyBigDecimalEditor(BigDecimal.class))
    }
}

评论

0赞 SGT Grumpy Pants 8/6/2013
另请参阅此页面上的最后一条评论 grails.1312388.n4.nabble.com/...
8赞 user520655 12/16/2010 #4

是否要显示原始数字?喜欢 100000?

您可以直接获取该字段:

${myBean.minPrice}

评论

3赞 Sudhir N 5/22/2012
如果使用 ${bean.value} 直接显示它,则无法显示未通过验证的值!
1赞 Torgny 3/11/2011 #5

改变

var x = <g:formatNumber number="${fieldValue(bean: personInstance, field: 'minPrice')}" format="#" />;

var x = <g:formatNumber number="${personInstance.minPrice}" format="#" />;
3赞 Kalisen 5/26/2011 #6

将“groupingUsed”属性与您的格式结合使用:

<g:formatNumber number="${fieldValue(bean: personInstance, field: 'minPrice')}" 
                format="#" 
                groupingUsed="true" />
1赞 Chris 8/30/2012 #7

我发现处理这个问题的最好方法是使用 PropertyEditor 做 Victor Sergienko(顺便说一句)暗示的事情。

为 Integer 创建一个编辑器,放入 src/groovy:

class IntegerEditor extends PropertyEditorSupport {
    void setAsText(String s) {
        if (s) value = s as Integer
    }

    public String getAsText() {
        value
    }
}

并使用 PropertyEditorRegistrar(也在 src/groovy 中)注册它:

class MyEditorRegistrar implements PropertyEditorRegistrar {
    public void registerCustomEditors(PropertyEditorRegistry reg) {
        reg.registerCustomEditor(Integer, new IntegerEditor())
    }
}

将注册器添加到 Spring 配置中 (grails-app/conf/spring/resource.groovy):

beans = {
    customEditorRegistrar(MyEditorRegistrar)
}

从现在开始,任何绑定、收到错误(或不接收错误)然后使用 fieldValue 标签重新显示的整数都应由 Integer 的默认 toString 显示 - 您可以通过修改 getAsText 实现在编辑器中自定义此行为。

就我个人而言,我会为这种事情创建一个包装器,这样你就可以只为该类型设置一个编辑器,而不是为一个常用的类型设置一个全面的编辑器。虽然我意识到这意味着在坚持到数据库时需要一点映射......

0赞 R.V.RaguPrashanth 12/23/2013 #8
Use like this :
<g:formatNumber number="${fieldValue(bean: personInstance, field: 'minPrice')}"
 format="#.##"/>;