You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vaadin 23中获取绑定的Lit元素内容?

问题描述

我按照Vaadin指南将元素绑定到Java类,代码如下:

@Id("editor")
private Div editor;
...
public List<Component> getEditorChilds(){
    List<Component> children = new ArrayList<>();
    editor.getChildren().forEach(children::add);
    return children;
}

调试时能拿到id为editor的Div实例,但调用getEditorChilds()获取子元素时得到空列表。

前端Lit组件代码:

@state() root: Element | null = null;
@state() content: string = "";

render() {
    return html`
        <main>
            <div id="editor-actions">
                <div id="toolbar">
                    ${toolbar(this.shadowRoot!, this.getSelection(), (command, val) => {
                        document.execCommand(command, false, val);
                        console.log("command", command, val);
                    })}
                </div>
            </div>
            <div id="editor">${this.root}</div>
        </main> `;
}

浏览器中该div的实际内容:

<div id="editor"><body contenteditable="true">
   Lorem <b>ipsum </b>dolor sit amet, consetetur sadipscing elitr, sed diam nonumy 
   eirmod tempor <br>invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
   At vero eos et accusam<br>...</body>
</div>

请问如何在Java类中获取该div或可编辑body的内容?能否直接从state属性获取?


解决方案

为什么getChildren()返回空列表?

Vaadin的Div.getChildren()仅能获取通过Vaadin组件API添加的Vaadin组件实例,而你前端渲染的<body>是原生DOM元素,不属于Vaadin组件范畴,因此Java端无法通过该方法读取到它。

方法1:通过自定义元素属性同步内容

在Lit组件中监听可编辑区域的内容变化,将HTML内容同步到组件的可反射属性上,Java端直接读取该属性即可:

  1. 修改Lit组件:
    // 将state改为可反射的property
    @property({reflect: true}) content: string = "";
    // 获取可编辑body的引用
    @query('body[contenteditable]') editableBody!: HTMLElement;
    
    connectedCallback() {
        super.connectedCallback();
        // 监听内容变化同步到content属性
        this.editableBody?.addEventListener('input', () => {
            this.content = this.editableBody.innerHTML;
        });
        // 初始化时同步一次内容
        this.content = this.editableBody?.innerHTML || "";
    }
    
  2. Java端读取内容:
    @Id("editor")
    private Div editor;
    
    public String getEditorContent() {
        // 直接读取组件的content属性
        return editor.getElement().getProperty("content");
    }
    

方法2:通过executeJs()直接读取DOM内容

如果不想修改Lit组件,可在Java端直接执行JS代码获取原生DOM的内容:

@Id("editor")
private Div editor;

public String getEditorContent() {
    // 执行JS查询并返回可编辑body的innerHTML
    return editor.getElement().executeJs("return this.querySelector('body[contenteditable]').innerHTML;")
            .toCompletableFuture()
            .join();
}

注意:该操作是异步的,生产环境建议使用CompletableFuture回调处理结果,避免直接join()阻塞线程。

能否直接从state属性获取?

不能。Lit的@state()标记的属性是内部状态,不会自动同步到DOM属性或Vaadin服务器端,必须通过@property({reflect: true})声明为可反射属性,才能让Java端读取到。


内容的提问来源于stack exchange,提问作者Matt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 21:02:26