Вопрос или проблема
На thymeleaf-3.1
th:include
устарел (
https://github.com/thymeleaf/thymeleaf/issues/913), поэтому я пытаюсь перенести свои включения, но без успеха.
Моя цель — создать фрагмент, который определяет элемент таблицы th
с набором данных.
Сейчас только для одного единственного элемента th в таблице я хочу применить другой css style
(в этом примере: text-align:right
).
Вот что у меня было раньше:
home.html
:
<table>
<thead>
<tr>
<th scope="col" th:include="~{components/tableheader :: tableheader('test')}"
style="text-align:right"/>
</tr>
</thead>
</table>
components/tableheader.html
:
<html xmlns="http://www.w3.org/1999/html" xmlns:th="http://www.thymeleaf.org">
<th scope="col" th:fragment="tableheader(text)">
<div th:text="${text}"/>
<!-- другие элементы -->
</th>
</html>
<table>
<thead>
<tr>
<th scope="col" style="text-align:right">
<div>test</div>
</th>
</tr>
</thead>
</table>
НО: th:include
устарел в последней версии thymeleaf, и рекомендуют использовать th:insert
.
Проблема: th:insert
теряет дополнительные стили и плюс вставляет “призрачную” строку, которая затем отображается как:
<table>
<thead>
<tr>
<th scope="col" style="text-align:right"></th> <!-- вот в чем проблема -->
<th scope="col">
<div>test</div>
</th>
</tr>
</thead>
</table>
Так что вы видите, я не могу просто заменить th:include. Как это можно исправить?
Ответ или решение
Для успешной миграции с th:include
на th:insert
в Thymeleaf 3.1, необходимо учитывать несколько важных моментов и придерживаться структуры, которая обеспечит корректное отображение ваших компонентов. Рассмотрим, как решить данную задачу на основе примера, который вы привели.
Проблема
Действительно, th:include
устарел, и в данном случае, его замена на th:insert
приводит к созданию лишнего элемента (<th>...</th>
) в результате вставки фрагмента и потере дополнительных стилей. Мы можем обойти эту проблему, изменяя способ определения ваших фрагментов и использования th:insert
.
Решение
-
Изменение Angular фрагмента: Вам потребуется сделать изменения в вашем фрагменте
components/tableheader.html
, чтобы он корректно воспринимал атрибуты стилей от родительского элемента. -
Передача стилей через атрибуты: Один из способов решения проблемы заключается в передаче стиля через атрибут. Для этого можно использовать
th:attr
, чтобы передать необходимые атрибуты в фрагмент.
Исправленная версия
Файл home.html
:
<table>
<thead>
<tr>
<th scope="col" th:insert="~{components/tableheader :: tableheader('test')}"
th:attr="style='text-align:right'"/>
</tr>
</thead>
</table>
Файл components/tableheader.html
:
<html xmlns="http://www.w3.org/1999/html" xmlns:th="http://www.thymeleaf.org">
<th scope="col" th:fragment="tableheader(text)" th:attr="style=${style}">
<div th:text="${text}"></div>
<!-- другие элементы -->
</th>
</html>
Объяснение
-
Использование
th:attr
: Вhome.html
, мы использовалиth:attr
для установки стиля непосредственно на элемент<th>
, который будет передан в фрагмент. Это предотвращает создание пустого элемента в результате примененияth:insert
. -
Передача параметров:
th:insert
теперь вызывает ваш фрагментtableheader
и передает нужные параметры, включая возможные стили черезth:attr
. Вcomponents/tableheader.html
, добавлен параметрth:attr="style=${style}"
, который получает стиль и применяет его к элементу<th>
.
Результат
После выполнения вышеописанных шагов, ваше окончательное HTML представление будет выглядеть корректно:
<table>
<thead>
<tr>
<th scope="col" style="text-align:right">
<div>test</div>
</th>
</tr>
</thead>
</table>
Заключение
С использованием этого подхода вы сможете избежать проблем, связанных с устаревшими атрибутами th:include
, и выполните их замену на th:insert
без потерь стилей и лишних элементов. Этот метод улучшит читаемость кода и облегчит его поддержку в будущем.