Reputation: 267
I want to display different Types of Objects (same supertype) in the same Grid. I want them rendered as Cards, with the help of Template Renderer. Suppose I want to build a webshop for PC-parts.
I would have an abstract Class AbstractPcPart
.
public abstract class AbstractPcPart {
private Price price;
private String name;
private Int stockQuantity;
// getters and setters
}
Now I want to have different Parts with different Fields.
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
}
I can display one Type in a List. This looks something like this: grid view with memory only Code for this List:
@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>"
}
Now this is fine and all, but when trying to build a grid with different template-renderers this does not work. I tried to add the fallowing Factory.
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
}
}
}
And changed the Grid to use this Factory.
@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))
}
This is not working as expected, instead of rendering the different Templates in my Grid, it is showing me the references to the template-renderers. template-renderer reference
If this is supposed to work, what am I doing wrong, and what do I need to change, that instead of showing the reference, the template gets rendered?
And if this is expected behaviour, what are viable alternatives?
Edit: I have built an example project and put it on github, for everyone to look at. Example-Project
The Application in the project contains a view vor every different method i used to fill a grid with templates. The fallowing views are present:
Upvotes: 0
Views: 246
Reputation: 4275
You can use conditional templates to a degree. The <dom-if if="item.isSomething">
template gets stamped if the isSomething
property is truthy. So you can use something like
"<template is='dom-if' if='[[item.first]]'>first template</template>
<template is='dom-if' if='[[item.second]]'>second template</template>
<template is='dom-if' if='[[item.third]]'>third template</template>"
which renders first template
if item.first
is true and so on. You need to supply the first
, second
and third
properties to the TemplateRenderer with something like .withProperty("first", item -> item.isFirst() ).withProperty("second", item -> item.isSecond())
and so on.
Upvotes: 3