如何在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端直接读取该属性即可:
- 修改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 || ""; } - 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
相关产品推荐
相关产品推荐

