Как я могу изменить способ GRAILS GSP fieldValue форматирует целые числа? - PullRequest
5 голосов
/ 21 января 2010

В моем доменном объекте есть поле, которое я определяю как целое число ...

Integer minPrice

Затем я получаю к нему доступ на странице GSP следующим образом:

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

и то, что я получаю в своем HTML, это ...

100,000

, который не является целым числом, это строка. Что еще хуже, это отформатированная строка в определенной локали.

Это проблема, потому что у меня есть элемент управления SELECT в HTML FORM, который имеет (не порядковый) диапазон значений для 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 для отправки обратно на сервер, оно правильно имеет целочисленное значение, которое я сохраняю. Однако обратная поездка никогда предварительно не выбирает правую строку в раскрывающемся списке, поскольку значением является строка, разделенная запятыми.

Это хорошо работает в другом месте в моем коде для небольших чисел, где форматирование запятых не вступает в игру, и круговая передача в и из SELECT успешна. Но значения> 999 не работают.

В документах написано "Этот тег будет проверять компонент, который был объектом привязки данных, и получать значение поля либо из первоначально переданного значения, содержащегося в объекте ошибок компонента, заполняемого во время привязки данных, либо из значение свойства бина. Как только значение получено, оно будет автоматически закодировано в HTML. "

Это последний бит, которого я хочу избежать, поскольку он выглядит для форматирования целых чисел. Итак, какую небольшую часть магии Grails / GSP мне нужно знать, чтобы я мог вывести мое Integer как целое число в мой SELECT и предварительно выбрать правильный ряд?

EDIT: Я попробовал кое-что еще, основываясь на ответах ниже, с довольно разочаровывающими результатами ...

Если я добавлю тег <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"
/>

Использование тега числового формата из GSP для моего целочисленного значения 100000, как это ...

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

дает 100. Помните, что fieldValue возвращает 100,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.

Полагаю, у меня есть более широкие опасения, чем то, что я не могу получить значение Integer как подлинное целое число в моем коде, если оно больше 999 из-за поведения по умолчанию (и не настраиваемого) директивы fieldValue. Однако моя конкретная проблема невозможности предварительно выбрать целочисленное значение в элементе управления SELECT не исчезла. В данный момент я немного растерялся.

У кого-нибудь есть еще идеи?

Ответы [ 8 ]

8 голосов
/ 15 декабря 2010

Хотите показать необработанный номер? как 100000?

Вы можете получить поле напрямую:

${myBean.minPrice}
5 голосов
/ 21 января 2010

Я думаю, у вас есть как минимум два возможных решения.

Одним из них является использование тега JSTL, как описано в документах .

Другой, более крутой способ - использовать тег «formatNumber», включенный в grails - также в документах .

Для вашей цели использование этого тега может выглядеть следующим образом:

<g:formatNumber number="${fieldValue(bean: myBean, field: 'minPrice')}" format="######" />
3 голосов
/ 26 мая 2011

Используйте атрибут groupingUsed в сочетании с вашим форматом:

<g:formatNumber number="${fieldValue(bean: personInstance, field: 'minPrice')}" 
                format="#" 
                groupingUsed="true" />
3 голосов
/ 14 декабря 2010

Лучше использовать custom PropertyEditor , чтобы не беспокоиться о теге formatNumber каждый раз, когда вы выводите значение. Мол, объявите боб в ресурсах. Groovy:

myOwnCustomEditorRegistrar(CustomEditorRegistrar)

И создайте свой класс:

class CustomEditorRegistrar implements PropertyEditorRegistrar {
    void registerCustomEditors(PropertyEditorRegistry registry) {
        registry.registerCustomEditor(BigDecimal.class, new MyBigDecimalEditor(BigDecimal.class))
    }
}
1 голос
/ 30 августа 2012

Я нашел, что лучший способ справиться с этим - делать то, на что намекал Виктор Сергиенко с помощью PropertyEditor.

Создайте редактор для 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.

Лично я бы создал оболочку для такого рода вещей, чтобы вы могли настроить редактор только для этого типа, а не по всем направлениям для часто используемого типа. Хотя я понимаю, что это будет означать немного отображения при сохранении в БД ...

1 голос
/ 11 марта 2011

Изменение

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

до

var x = <g:formatNumber number="${personInstance.minPrice}" format="#" />;
0 голосов
/ 23 декабря 2013
Use like this :
<g:formatNumber number="${fieldValue(bean: personInstance, field: 'minPrice')}"
 format="#.##"/>;
0 голосов
/ 22 января 2010

У меня есть решение / обходной путь ... Кажется, ответ "ничего не делать".

Вместо того, чтобы пытаться разобрать строковое число обратно в целое число, я оставил его как отформатированную строку для целей выбора. Это означало, что мне пришлось изменить мои 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 до сохранения.

Это прекрасно работает для моих целей, однако я думаю, что это в основном обходной путь, а не решение из-за региональных проблем. Если мой разделитель тысяч - это "." и мой десятичный разделитель - ",", что для большей части Европы, тогда мой код не будет работать.

...