【发布时间】:2021-12-01 00:22:48
【问题描述】:
我想在同一个网格中显示不同类型的对象(相同的超类型)。我希望它们在模板渲染器的帮助下呈现为卡片。假设我想为 PC 零件建立一个网上商店。
我会有一个抽象类AbstractPcPart。
public abstract class AbstractPcPart {
private Price price;
private String name;
private Int stockQuantity;
// getters and setters
}
现在我想要拥有不同字段的不同部分。
public class GraphicsCard extends AbstractPcPart {
private List<Connector> connections;
private CoolingSystem coolingSystem;
private int PciExpressVersion;
private String cardModel;
// getters and setters
}
public class Memory extends AbstractPcPart {
private MemoryConfiguration configuration;
private String formFactor;
private int frequency;
// getters and setters
}
我已经拥有的
我可以在列表中显示一个类型。这看起来像这样: grid view with memory only 此列表的代码:
@JsModule("./src/views/parts/card/memory-card.js")
public class PcPartsGrid extends Grid<AbstractPcPart> {
public PcPartsGrid() {
super();
addColumn(MemoryCard.getTemplate()
.withProperty("partCard", MemoryCard::create))
}
public class MemoryCard extends AbstractPcPartCard {
AbstractPcPart pcPart;
public MemoryCard (AbstractPcPart pcPart) {
this.pcPart = pcPart;
}
public static MemoryCard create(AbstractPcPart pcPart) {
return new MemoryCard(pcPart)
}
public static TemplateRenderer<AbstractPcPart> getTemplate() {
return TemplateRenderer.of(
"<memory-card memory-card='[[item.partCard]]'>"
+ "</memory-card>"
}
有什么问题?
现在这很好,但是当尝试使用不同的模板渲染器构建网格时,这不起作用。 我尝试添加休闲工厂。
public class CardFactory {
public static AbstractPcPart create(AbstractPcPart pcPart) {
if (pcPart.getClass() == GraphicsCard.class) {
return GraphicsCardCard.create(pcPart);
} else if (pcPart.getClass() == Memory.class) {
return MemoryCard.create(pcPart);
} else {
// different Pc Parts
}
}
public static TemplateRenderer<AbstractPcPart> getTemplate(AbstractPcPart pcPart) {
if (pcPart.getClass() == GraphicsCard.class) {
return GraphicsCardCard.getTemplate();
} else if (pcPart.getClass() == Memory.class) {
return MemoryCard.getTemplate();
} else {
// different Pc Parts
}
}
}
并更改了网格以使用此工厂。
@JsModule("./src/views/parts/card/memory-card.js")
@JsModule("./src/views/parts/card/graphics-card-card.js")
public class PcPartsGrid extends Grid<AbstractPcPart> {
public PcPartsGrid() {
super();
addColumn(pcPart -> CardFactory.getTemplate(pcPart)
.withProperty("partCard", CardFactory::create))
}
这没有按预期工作,它不是在我的网格中呈现不同的模板,而是向我显示对模板渲染器的引用。 template-renderer reference
如果这应该工作,我做错了什么,我需要改变什么,而不是显示参考,模板被渲染?
如果这是预期行为,有哪些可行的替代方案?
编辑: 自己搭建了一个示例项目,放到github上,供大家看看。 Example-Project
项目中的应用程序包含一个视图,用于我使用模板填充网格的每种不同方法。休闲的观点是存在的:
- 原始视图(我一开始就是这样,只为一个版本的 pcPart 使用模板渲染器)
- 使用 Cardfactory 查看(该工厂旨在为每种类型的 pcPart 使用不同的模板)这仅显示对对象的引用而不是模板(我认为这是因为我在 addColumn() 中使用了 lambda我从 vaadin Grid 继承的方法)
- 使用 dom-if 元素查看(此视图使用 dom-if 元素,如 ollitietavainen 中的 this answer 中所述,遗憾的是它没有按预期工作:它显示两个模板而不是一个模板)
- 不使用模板的视图(这只是一个使用值提供者的简单网格)
- 使用组件渲染器的视图
- 来自Vaadin 的示例视图也使用了组件渲染器
【问题讨论】:
标签: java vaadin-flow vaadin-grid