瓦丁23。
我们将html存储在数据库中,我们需要在vaadin组件中呈现该数据库。
html包含一个web组件“文本块”
文本块可以包含嵌套的子项:
<p>
<text-block page="PackageSearch" block="empty-search-Sign up for free" class="gimps">
<div class="glimps-tips" id="glimps-tips">
<h3>Sign up for free</h3>
Create a watch and get notifications when a new package version is released.<br>
</div>
</text-block>
<p>
问题是当
<text-block>
在浏览器中渲染时,子节点被渲染为兄弟节点而不是子节点:
<p>
<text-block page="PackageSearch" block="empty-search-Sign up for free" class="gimps">
</text-block>
<div class="glimps-tips" id="glimps-tips">
<h3>Sign up for free</h3>
Create a watch and get notifications when a new package version is released.<br>
</div>
</p>
我已经将问题归结为Vaadin Element类使用Jsoup这一事实,Jsoup不喜欢web组件,因此作为其“验证”的一部分,它会重新订购组件。
我相信vaadin正在使用`Element.getOuterHtml()`来完成html的最终渲染,它调用:
public String getOuterHTML() {
return ElementUtil.toJsoup(new Document(""), this).outerHtml();
}
我已经尝试创建一个类RawHtml:
import com.vaadin.flow.component.html.Div;
public class RawHtml extends Div
{
private static final long serialVersionUID = 1L;
public RawHtml(String html)
{
getElement().setProperty("innerHTML", html);
}
public String html() {
return getElement().getProperty("innerHTML");
}
@Override
public String toString() {
return html();
}
}
然后我使用这个类将html添加到VerticalLayout
var body = new VerticalLayout();
body.add(new RawHtml(< html with textblock and nested div as above>);
结果是一样的。div被移动到文本块之外。
我的理论是,vaadin在将html发送到浏览器之前,使用jsoup对其进行最终渲染。
我该怎么解决这个问题。
编辑:根据Leif的建议更新了问题。
编辑2:
现在,我已经通过vaadin堆栈将html追溯到UidlRequestHandler.commitJsonResponse中的调用。
片段传递到
json
的论点
commitJsonResponse
有
div正确地嵌套在文本块中:
{"node":267,"type":"put","key":"innerHTML","feat":1,
"value":"<div>
<span><p>
<a href=\"/Blog#link-in-page\">hi</a>
<text-block page=\"PackageSearch\" block=\"empty-search-Sign up for free\" class=\"gimps\">\n
<div>\n
<div class=\"glimps-tips\" id=\"glimps-tips\">\n
<h3>Sign up for free</h3> Create a watch and get notifications when a new package version is released.<br>
Publish your own private packages.<br> Access your API documentation online.<br> Share packages with your team.<br>
Be more productive<br>\n
</div>\n
</div>\n
</text-block>
所以现在看来我的问题不是服务器端,而是客户端。
以下是浏览器生成内容的屏幕截图:
我还可以看到浏览器收到了正确的html:
因此,重新排序必须在浏览器上进行。
vaadin在将html添加到DOM时是否对其进行任何操作?这感觉不太可能。
这似乎表明浏览器正在重新排序,这表明我的web组件实现是错误的?
编辑3:
所以我的下一个想法是我的web组件坏了。
为了验证它,我使用这个测试站点:
https://stackblitz.com/edit/nested-slots-subkxj?file=my-element.js,index.html,package.json
进入我的web组件并证明它工作正常(div在插槽中呈现)。
这是我的web组件:
import { html, LitElement } from 'lit';
export class TextBlock extends LitElement {
render() {
return html`
<div class='me'>
<slot name="one"></slot>
</div>
`;
}
}
customElements.define('text-block', TextBlock);
以下是它的渲染方式: