You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Thymeleaf自定义标签实现子元素循环渲染(替代th:each)

实现自定义循环标签并获取子元素的解决方案

一、优先选择AbstractElementModelProcessor实现

要处理包含子元素的自定义标签,AbstractElementModelProcessor是更合适的选择——它直接面向模板模型节点树操作,能轻松获取和处理子元素;而AbstractAttributeTagProcessor主打属性逻辑处理,没有直接获取子元素的便捷API,操作起来冗余复杂。

二、具体实现步骤

1. 创建自定义处理器类

继承AbstractElementModelProcessor,指定自定义标签的命名空间、标签名和优先级:

public class CategoryLoopProcessor extends AbstractElementModelProcessor {

    // 自定义标签的命名空间(需与模板中声明的一致)
    private static final String NAMESPACE = "http://your-domain.com/my";
    private static final String TAG_NAME = "categoty";
    // 优先级,数值越低越先执行
    private static final int PRECEDENCE = 1000;

    public CategoryLoopProcessor() {
        super(NAMESPACE, TAG_NAME, PRECEDENCE);
    }

2. 核心逻辑实现

在doProcess方法中完成属性解析、子元素获取、循环复制的核心逻辑:

@Override
    protected void doProcess(ITemplateContext context, IModel model, IProcessableElementTag tag) {
        // 1. 解析loop属性的循环次数
        String loopAttrValue = tag.getAttributeValue("loop");
        int loopCount;
        try {
            loopCount = Integer.parseInt(loopAttrValue);
        } catch (NumberFormatException e) {
            // 处理属性无效的情况,默认设为1
            loopCount = 1;
        }

        // 2. 获取自定义标签的所有子元素模型
        // splitElement会将当前标签的子元素分离出来,返回独立的子模型
        IModel childElementsModel = model.splitElement(tag);

        // 3. 循环复制子元素并添加到模板模型中
        for (int i = 0; i < loopCount; i++) {
            // 克隆子模型(避免引用同一实例导致异常)
            model.addModel(childElementsModel.cloneModel());
        }

        // 4. 移除原自定义标签节点,只保留循环后的子元素
        model.remove(tag);
    }
}

3. 注册处理器

在Spring配置类中注册这个自定义处理器,让Thymeleaf能识别并执行它:

@Configuration
public class ThymeleafConfig {
    @Bean
    public CategoryLoopProcessor categoryLoopProcessor() {
        return new CategoryLoopProcessor();
    }
}

4. 模板中使用自定义标签

记得在模板开头声明命名空间,然后使用自定义标签:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:my="http://your-domain.com/my">
<head>
    <title>自定义循环标签示例</title>
</head>
<body>
<my:categoty loop="5">
    <div class="item">这是循环渲染的内容</div>
</my:categoty>
</body>
</html>

三、关键API说明

  • model.splitElement(tag):这是获取子元素的核心方法,它会把当前自定义标签的所有子节点从原模型中分离出来,返回一个包含这些子节点的新IModel实例,原模型仅保留自定义标签本身。
  • childElementsModel.cloneModel():每次循环都需要克隆子模型,因为直接添加同一模型实例会导致节点重复引用的异常。

内容的提问来源于stack exchange,提问作者疯狂的小智

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 16:00:14