Как контролировать значимые цифры, только при необходимости, в шаблоне Thymeleaf?
при использовании th:text
атрибут чтобы оценить и отобразить числовое поле, Thymeleaf отображает полное количество доступных цифр. Например, это:
<span th:text="${user.averageScore}"/>
... может отображаться на экране браузера:
107.54896
Я хотел бы отобразить эту сумму, округленную не более чем до двух знаков после запятой. Из документации Thymeleaf, это:
<span th:text="${#numbers.formatDecimal(user.averageScore, 0, 2)}"/>
... изменяет вывод следующим образом:
107.55
однако, есть ли способ сделать это более гибко... в случаях, когда значение имеет менее двух знаков после запятой? Я хочу удалить только десятичные знаки, чтобы сократить до двух. Я никогда не хочу добавлять десятичные знаки, чтобы получить до двух. Если поле выше имеет значение 107, то оно будет отображаться как:
107.00
как я могу сделать номера формата Thymeleaf для двух десятичных знаков или меньше... вместо двух знаков после запятой, несмотря ни на что?
2 ответов
привет, вы можете попробовать что-то вроде этого.
<span th:text="${user.averageScore} % 1 == 0? ${user.averageScore} :${#numbers.formatDecimal(user.averageScore, 0, 2)}"/>
в Thymeleaf 2.1 нет простого способа сделать это, но есть два трудных способа.
Hard way #1: Fork Thymeleaf и добавьте метод format в класс org.thymeleaf.выражение.Числа, которые делают то, что вы хотите (добавление метода, который принимает шаблон DecimalFormat, будет выглядеть как логическое расширение)
Hard way #2: Добавьте диалект в Thymeleaf, который предоставляет новый класс выражений, который выполняет форматирование, которое вы хотите. Мой пример ниже основан на использовании Spring с Thymeleaf чтобы зарегистрировать диалект для форматирования чисел, представляющих часы.
Шаг 1: зарегистрируйте диалект:
@Component
public class ThymeLeafSetup implements InitializingBean {
@Autowired
private SpringTemplateEngine templateEngine;
@Override
public void afterPropertiesSet() throws Exception {
templateEngine.addDialect(new HoursDialect());
}
}
Шаг #2: Создайте класс диалекта (логика форматирования, делегированная статическому методу TimeUtils) - на основе Java8TimeDialect:
public class HoursDialect extends AbstractDialect implements IExpressionEnhancingDialect {
public static class Hours {
public String format(BigDecimal hours) {
return TimeUtils.formatHours(hours);
}
}
@Override
public String getPrefix() {
// No attribute or tag processors, so we don't need a prefix at all and
// we can return whichever value.
return "hours";
}
@Override
public boolean isLenient() {
return false;
}
@Override
public Map<String, Object> getAdditionalExpressionObjects(IProcessingContext processingContext) {
return Collections.singletonMap("hours", new Hours());
}
}
Шаг #3: Создайте логику форматирования на основе DecimalFormat
public class TimeUtils {
public static String formatHours(BigDecimal hours) {
DecimalFormat format = new DecimalFormat("#0.##");
format.setGroupingUsed(true);
format.setGroupingSize(3);
return format.format(hours);
}
}
Шаг #4: тесты логики форматирования
@Test
public void formatDecimalWilLFormatAsExpected() {
verifyHourNumberFormatsAsExpected("1.5", "1.5");
verifyHourNumberFormatsAsExpected("1.25", "1.25");
verifyHourNumberFormatsAsExpected("123.0", "123");
verifyHourNumberFormatsAsExpected("1230", "1,230");
}
void verifyHourNumberFormatsAsExpected(String number, String expected) {
assertThat(TimeUtils.formatHours(new BigDecimal(number))).isEqualTo(expected);
}