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

Vaadin Grid中使用多个Template渲染同父类不同子类对象问题咨询

问题根因

你当前的写法误用了Grid的addColumn重载方法:
你传入的lambda表达式属于ValueProvider类型,这个重载的作用是把返回值转为字符串直接展示,你返回TemplateRenderer对象自然只会输出对象的toString结果,不会触发模板渲染。addColumn接受Renderer的重载要求你直接传入固定的Renderer实例,不支持按行动态返回不同的Renderer。


方案1:统一模板+dom-if判断(推荐,性能最优)

你之前用dom-if出现两个模板同时展示的问题,是因为没有正确设置判断条件和restamp属性,正确写法如下:
首先定义统一的模板:

public static TemplateRenderer<AbstractPcPart> getUnifiedTemplate() {
    return TemplateRenderer.of("""
            <template is="dom-if" if="[[item.isMemory]]" restamp>
                <memory-card memory-card='[[item.partCard]]'></memory-card>
            </template>
            <template is="dom-if" if="[[item.isGraphicsCard]]" restamp>
                <graphics-card-card graphics-card='[[item.partCard]]'></graphics-card-card>
            </template>
            """)
            .withProperty("isMemory", part -> part instanceof Memory)
            .withProperty("isGraphicsCard", part -> part instanceof GraphicsCard)
            .withProperty("partCard", CardFactory::create);
}

然后Grid初始化的时候直接传入这个统一模板即可:

public PcPartsGrid() {
    super();
    addColumn(getUnifiedTemplate());
}

restamp属性会保证条件切换时旧的组件被销毁,不会同时出现两个组件。


方案2:ComponentRenderer实现(写法最简单)

如果你对性能要求不是极致高(单页数据量小于100条的场景几乎感知不到差异),用ComponentRenderer逻辑更直观,不需要写前端模板判断:

public PcPartsGrid() {
    super();
    addColumn(new ComponentRenderer<>(pcPart -> {
        if (pcPart instanceof Memory) {
            return new MemoryCardComponent((Memory) pcPart);
        } else if (pcPart instanceof GraphicsCard) {
            return new GraphicsCardComponent((GraphicsCard) pcPart);
        }
        return new Span("未知配件");
    }));
}

你只需要把之前的前端模板封装成对应的Vaadin组件即可,代码逻辑全在Java侧控制,不容易出错。


方案3:自定义渲染器(适合复杂场景)

如果确实需要完全动态的模板渲染,可以自己实现Renderer<AbstractPcPart>接口,在render方法里根据当前行数据的类型选择不同的渲染逻辑,不过实现复杂度较高,一般前两个方案就能覆盖绝大多数场景。

内容的提问来源于stack exchange,提问作者Dario Viva

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 00:09:02