繁体   English   中英

原始 html 中的 vaadin 网络组件

[英]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,因此作为其“验证”的一部分,它会重新排序组件。

我相信 vaadin 正在使用 `Element.getOuterHtml()` 来完成 html 的最终渲染,它调用:
 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 中的调用。

传递给commitJsonResponsejson参数的片段将 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM