我将一个Vaadin8项目迁移到Vaadin14,并尝试在网格列中显示HTML。我明白了,我必须使用TemplateRenderer,但是我如何使用它呢?
这是来自Vaadin 8的代码:
grid.addColumn(e -> {
return ((Data) e).getValues()[index];
}).setCaption(myCaption).setRenderer(new HtmlRenderer());在Vaadin 14中,我这样做了:
gird.addColumn(e -> {
return TemplateRenderer.<Data>of((String) e.getValues()[index])
}).setHeader(myCaption);e.getValues()[index]包含超文本标记语言,例如:<FONT SIZE = 4 COLOR = BLACK> ⚫</FONT>
在Vaadin14中,它总是返回com.vaadin.flow.data.renderer。
发布于 2019-11-25 16:18:39
在我们开始讨论如何在网格中使用TemplateRenderer之前,我首先需要指出的是,如果您想要显示的HTML字符串可能是由应用程序用户提供的,那么您正在尝试做的事情是潜在的危险,因为它可能会导致XSS漏洞。
使用Html组件确实是此问题的一个潜在解决方案,但它会带来一些开销,因为对于网格中的每一行,内存中都会有一个组件实例。潜在地导致XSS漏洞也存在同样的问题。
使用TemplateRenderer需要注意的第一件事是,渲染器需要作为参数直接提供给addColumn。将其包装在lambda中将改为使用该lambda作为值提供者,这意味着渲染器实例的toString()值将与默认的纯文本渲染器一起使用。
所有行都应该使用相同的渲染器实例,并使用相同的模板字符串进行配置。诀窍在于,您可以传递数据以显示为模板将为您呈现的每行属性。最后一个难题是,模板语法试图保护您免受意外的XSS漏洞的影响,因此您需要使用稍微人为设计的语法来实际将数据呈现为HTML。
将所有东西放在一起,并使用JSoup从HTML字符串中删除任何危险的东西,工作解决方案看起来如下所示:
grid.addColumn(TemplateRenderer
.<Data> of("<div inner-h-t-m-l='[[item.html]]'></div>")
.withProperty("html", e -> {
String unsafeHtml = e.getValues()[index];
String safeHtml = Jsoup.clean(unsafeHtml, Whitelist.basic());
return safeHtml;
})).setHeader(myCaption);发布于 2019-11-22 17:37:18
我找到了一个解决方案。我使用的是ComponentRenderer,而不是TemplateRenderer。迁移文档建议使用TempleteRenderer或ComponentRenderer而不是htmlRenderer。
https://vaadin.com/docs/v14/flow/migration/8-migration-example.html#step-4-product-grid
以下是为我工作的代码:
grid.addColumn(new ComponentRenderer<>(e -> {
String value = (String) e.getValues()[index];
return new Html(value);
})).setHeader(String.valueOf(col + 1));发布于 2019-11-22 18:30:20
将您的尝试与TemplateRenderer和documentation进行比较,我假设它必须如下所示:
grid.addColumn(e ->
TemplateRenderer.<Data>of("[[item.customValue]]")
.withProperty("customValue", (String) e.getValues()[index])
).setHeader(myCaption);https://stackoverflow.com/questions/58956707
复制相似问题