微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

瓦丁 18 |需要使用 Lit-Template 和 HTML 文本将消息从客户端传递到服务器

如何解决瓦丁 18 |需要使用 Lit-Template 和 HTML 文本将消息从客户端传递到服务器

我正在尝试使用 littemplate 从客户端调用服务器端函数我有一个问题需要帮助。 我在服务器端添加一个 HTML fromatted 文本,它有一个自定义组件“hello-world2”。

在这自定义组件中传递了一个属性(name="Vaadin")。我希望当用户单击“helloButton”时,应将值“Vaadin”发送到服务器并调用“acceptMessage”。 但截至目前,我收到了附加屏幕截图中显示错误

我这样做是因为在我当前的应用程序中我已经生成了 HTML 表格。对于一些列,我尝试合并和使用 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;
}

enter image description here

enter image description here

解决方法

如果您希望 Java 中的 HelloWorldView 代表 <hello-world2> 客户端自定义元素的 Java API,它应该扩展 Component(或者 LitTemplate,如果您想使用 { {1}} 注释)而不是 @Id,您应该取消注释 HorizontalLayout 注释并删除 @Tagnew 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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?