[英]vaadin web-component in raw html
瓦丁 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 class 使用不喜欢 Web 组件的 Jsoup,因此作为其“验证”的一部分,它会重新排序组件。
public String getOuterHTML() { return ElementUtil.toJsoup(new Document(""), this).outerHtml(); }
我试过创建一个 class 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(); } }
然后我使用这个 class 将 html 添加到 VerticalLayout
var body = new VerticalLayout(); body.add(new RawHtml(< html with textblock and nested div as above>);
结果是一样的。 div 被移到文本块之外。
我的理论是 vaadin 在将其发送到浏览器之前使用 jsoup 对 html 进行了最终渲染。
我该如何解决这个问题。
编辑:更新问题以回应 Leif 的建议。
编辑 2:
我现在已经通过 vaadin 堆栈将 html 追溯到 UidlRequestHandler.commitJsonResponse 中的调用。
传递给commitJsonResponse
的json
参数的片段将 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:
所以重新排序必须发生在浏览器上。
将 html 添加到 DOM 时,vaadin 是否对其进行任何操作? 这感觉不太可能。
似乎表明浏览器正在重新排序,这表明我的 web 组件实现是错误的?
编辑 3:所以我的下一个想法是我的网络组件坏了。 为了验证它,我使用了这个测试站点: 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);
这是它的呈现方式:
您没有说明您使用哪个 Vaadin 组件来呈现 HTML 内容,因此我假设它是内置的Html
组件。 该组件使用 JSoup 解析 HTML 以便能够将 HTML 的根标签设置为自己的标签名称,而不是将其包装在另一个元素中,然后将 HTML 的 rest 设置为自己的内容。
如果你想将 HTML 片段按原样传递给浏览器,那么你可以通过创建自己的包装器组件来实现,该包装器组件通过Element
API 将原始 HTML 字符串设置为其innerHTML
属性。
public class RawHtml extends Div {
public void setHtml(String html) {
getElement().setProperty("innerHTML", html);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.