如何使用 Web 组件或 lit-html 呈现表单中的值?

How to render the value in the form using web components or lit-html?

我正在使用 lit-html 库将数据渲染到表单中。

程序应在输入产品编号后自动填写产品名称。我已经编写了代码,但无法自动填写产品名称字段。对于产品名称,我在 JavaScript 代码中使用了静态虚拟数据。

有没有办法仅使用 Web 组件或使用库 'lit-html' 来做到这一点?

下面你可以找到我的代码

import {html, render} from 'lit-html'

class MyApp extends HTMLElement {
    constructor() {
        super()
        this.attachShadow({mode: 'open'});
        const forms = () => {
            const productNum = new Array();
            const productName = new Array();

            productNum[0] = 123;
            productName[0] = 'Paper';
            productNum [1] = 500;
            productName[1] = 'Laptop';

            function details(products) {
                if (products > 50) {
                    for (let i = 0; i < productNum.length; i++) {
                        if (products == productNum[i]) {
                            this.info.product.value = productName[i]
                        } else {
                            this.info.product.value = ''
                        }
                    }
                }
            }

            return html` <form name = 'info'>
                  <input type="text" name="product" onkeyup="${details(parseInt(this.value, 10))}" maxlength=3>ProductNum
                  <input type="text" name="productName" onkeyup="">ProductName
                </form>`

        }
        const template = html`
            ${forms()}`

        render(template, this.shadowRoot)
    }

}


window.customElements.define('my-app', MyApp)

Objective:(自动)用(产品)数据填写相关表单字段

一种(本机)组件方式是让 FORM 处理对产品数据的查询
通过事件传达产品信息

这样组件之间就没有依赖关系(事件名称除外),
您可以根据需要获得尽可能多的相关输入。

相关自定义元素代码:

<my-form>
  <my-input name="productkey"></my-input>
  <my-input name="productname"></my-input>
</my-form>
customElements.define("my-form", class extends HTMLElement {
  constructor() {
    super();
    let products = productDatabaseMap();
    this.addEventListener("getProduct", evt => {
      let detail={
        product: products[evt.detail.value],
        input: evt.target // input that requested product details
      };
      dispatchEvent(this, "setProduct", detail);
    });
  }
})
customElements.define("my-input", class extends HTMLElement {
  constructor() {
    super();
    let input = this.appendChild(document.createElement('input'));
    let name = input.placeholder = this.getAttribute('name');
    this.onkeyup = evt => dispatchEvent(input, "getProduct", evt.target);
    this.closest("my-form").addEventListener("setProduct", evt => {
      let product = evt.detail.product;
      if (product instanceof Product) input.value = product[name];
      else if (evt.detail.input !== input) input.value = '';
    });

  }
})
  • 数据存储在 Map 中,同时将 productkey 和 productname 作为查找键
  • 每次输入按键都会发送一个 "getProduct" 事件 UP DOM 树
  • my-form 上的事件侦听器从查找映射中获取产品
  • 表单使用产品或未定义的产品调度 "setProduct" 事件
  • 所有输入 侦听 "setProduct" 事件
  • 如果产品被退回所有输入字段设置相应的值

工作 JSFiddle:https://jsfiddle.net/CustomElementsExamples/4fq7wnt9/

If you wrap <my-input> in a shadowRoot you need more boilerplate code and be aware event.detail then needs composed:true to make it cross shadow boundaries. And event.target will reference the (last) component it came from... not the input field that triggered that event