如何解决瓦丁 18 |需要使用 Lit-Template 和 HTML 文本将消息从客户端传递到服务器
我正在尝试使用 littemplate 从客户端调用服务器端函数。我有一个问题需要帮助。 我在服务器端添加一个 HTML fromatted 文本,它有一个自定义组件“hello-world2”。
我在这个自定义组件中传递了一个属性(name="Vaadin")。我希望当用户单击“helloButton”时,应将值“Vaadin”发送到服务器并调用“acceptMessage”。 但截至目前,我收到了附加屏幕截图中显示的错误。
我这样做是因为在我当前的应用程序中我已经生成了 HTML 表格。对于一些列,我尝试合并和使用
请指导我如何做到这一点。
点亮模板
ImmutablePair
Java
// hello-world2.ts
import { customElement,html,LitElement,property } from "lit-element";
import "@vaadin/vaadin-button/vaadin-button";
import "@vaadin/vaadin-text-field/vaadin-text-field";
import "@vaadin/vaadin-ordered-layout/vaadin-vertical-layout";
import { showNotification } from "@vaadin/flow-frontend/a-notification";
@customElement('hello-world2')
export class HelloWorld extends LitElement {
public $server1?: HelloWorldServerInterface;
@property({ type: String })
name = '';
render() {
return html`<vaadin-vertical-layout theme="padding spacing">
<vaadin-button id="helloButton" @click="${this.sendMessage}">Message Button</vaadin-button>
</vaadin-vertical-layout>`;
}
sendMessage() {
showNotification("Hello : " + this.name); //Works well,displays the notification
this.$server1!.acceptMessage(this.name); // Issue here.
}
}
interface HelloWorldServerInterface {
greet(): void;
acceptMessage(arg0: String): void;
}
解决方法
如果您希望 Java 中的 HelloWorldView
代表 <hello-world2>
客户端自定义元素的 Java API,它应该扩展 Component
(或者 LitTemplate
,如果您想使用 { {1}} 注释)而不是 @Id
,您应该取消注释 HorizontalLayout
注释并删除 @Tag
和 new Html
部分。
当您拥有 add(html)
时,这意味着通过向页面添加 @Tag("hello-world2")
,它实际上添加了 HelloWorldView
,因为它随后被视为此 Java 组件的客户端表示。因此,当您还在构造函数中手动为其添加 HTML 时,您最终会得到 <hello-world2></hello-world2>
(这就是为什么您会看到两倍的内容)。
现在,当您在这里注释掉 <hello-world2><hello-world2></hello-world2></hello-world2>
并扩展 @Tag
时,这意味着 HorizontalLayout
= HelloWorldView
组件因为它继承了 <vaadin-horizontal-layout>
{1}}(而不是您的 @Tag("vaadin-horizontal-layout")
自定义元素的直接 Java API)。然后 HorizontalLayout
实例将获得 <hello-world2>
方法,因此您不能从 <vaadin-horizontal-layout>
中的 $server.acceptMessage()
调用它,因为它只会在其父级上声明。
这是我认为您正在尝试做的事情(或类似的事情)的一个有效示例(我测试过它有效):
this
<hello-world2>
hello-world2.ts
:
import { customElement,html,LitElement,property } from 'lit-element';
import '@vaadin/vaadin-button/vaadin-button';
import '@vaadin/vaadin-ordered-layout/vaadin-vertical-layout';
import { showNotification } from '@vaadin/flow-frontend/a-notification';
@customElement('hello-world2')
export class HelloWorld2View extends LitElement {
$server?: HelloWorldServerInterface;
@property({ type: String })
name = '';
render() {
return html`
<vaadin-vertical-layout theme="padding spacing">
<vaadin-button id="helloButton" @click="${this.sendMessage}">Message Button</vaadin-button>
</vaadin-vertical-layout>
`;
}
sendMessage() {
showNotification("Hello : " + this.name);
this.$server!.acceptMessage(this.name);
}
}
interface HelloWorldServerInterface {
greet(): void;
acceptMessage(arg0: String): void;
}
我不确定这里的 HelloWorld2View.java
属性究竟是什么用例,或者为什么你想在组件的构造函数中设置它,但在这里我还为它添加了一个 setter Java API。或者,您也可以在 TS 文件中为 package com.example.application.views.helloworld;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.router.PageTitle;
import com.example.application.views.MainLayout;
import com.vaadin.flow.component.ClientCallable;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.Tag;
import com.vaadin.flow.component.dependency.JsModule;
@Route(value = "hello",layout = MainLayout.class)
@PageTitle("Hello World")
@Tag("hello-world2")
@JsModule("./views/littemplate/hello-world2.ts")
public class HelloWorld2View extends Component {
public HelloWorld2View() {
setName("Vaadin");
}
public void setName(String name) {
getElement().setProperty("name",name);
}
@ClientCallable
public void acceptMessage(String message) {
System.out.println("Message from client : " + message);
}
}
设置默认值,而不是在 Java 构造函数中设置它。
似乎您可能希望此 name
成为旨在添加到视图的组件(而不是单独表示整个视图)。在这种情况下,您应该专门为此组件提供 TS 和 Java 文件(如上),然后在某些视图中使用它,上面的 name
可能应该仅命名为 <hello-world2>
或类似名称,以免混淆成为一个视图。
HelloWorld2View
或
HelloWorld2
,
这是另一个工作示例,它可能更接近您想要的。
hello-world2.ts
:
import { customElement,property } from 'lit-element';
import '@vaadin/vaadin-button/vaadin-button';
import '@vaadin/vaadin-ordered-layout/vaadin-vertical-layout';
import { showNotification } from '@vaadin/flow-frontend/a-notification';
@customElement('hello-world2')
export class HelloWorld2 extends LitElement {
@property({ type: String })
name = '';
render() {
return html`
<vaadin-vertical-layout theme="padding spacing">
<vaadin-button id="helloButton" @click="${this.sendMessage}">Message Button</vaadin-button>
</vaadin-vertical-layout>
`;
}
sendMessage() {
const $server = (this.parentElement as HtmlElementWithMyViewServerInterface).$server;
showNotification("Hello : " + this.name);
$server!.acceptMessage(this.name);
}
}
interface MyViewServerInterface {
acceptMessage(message: String): void;
}
interface HtmlElementWithMyViewServerInterface extends HTMLElement {
$server?: MyViewServerInterface;
}
MyView.java
:
@Route(value = "myview",layout = MainLayout.class)
@PageTitle("My View")
@JsModule("./views/littemplate/hello-world2.ts")
public class MyView extends HorizontalLayout {
public MyView() {
Html html = new Html("<hello-world2 name='Vaadin'></hello-world2>");
add(html);
}
@ClientCallable
public void acceptMessage(String message) {
System.out.println("Message from client : " + message);
}
}
尽管理想情况下您还有一个用于 <hello-world2>
的 Java 组件类,并在视图中使用它而不是 Html
组件。可能看起来像这样:
HelloWorld2.java
:
@Tag("hello-world2")
@JsModule("./views/littemplate/hello-world2.ts")
public class HelloWorld2 extends Component {
public HelloWorld2() {
setName("");
}
public HelloWorld2(String name) {
setName(name);
}
public void setName(String name) {
getElement().setProperty("name",name);
}
}
MyView.java
:
@Route(value = "myview",layout = MainLayout.class)
@PageTitle("My View")
public class MyView extends HorizontalLayout {
public MyView() {
add(new HelloWorld2("Vaadin"));
}
@ClientCallable
public void acceptMessage(String message) {
System.out.println("Message from client : " + message);
}
}
,
Vaadin 设置了一个名为 $server 的变量,您无法更改此名称。这就是您出现错误的原因,因为 $server1 不存在。
您应该将 $server1 重命名为 $server 并且它应该可以工作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。