繁体   English   中英

在点亮元素中更改数据后更新 HTML 输入元素的正确方法是什么?

[英]What is the correct way of updating a HTML Input element after data changed in a lit-element?

我在使用lit-element自定义 web 组件的应用程序中有一个错误:手动编辑 HTML 输入元素时,内部组件 state 中的更改不再反映在该元素中。 但是,在进行任何手动编辑之前,这些值会正确反映。

我似乎错过了一些关于 HTML 元素属性如何工作的知识。 要么,要么我缺乏有关点燃元素的知识。

我怀疑 DOM 节点的详细工作方式。 但我可能错了。 似乎只要对“输入”元素进行手动编辑,它的行为就会发生变化,并且它总是保持用户价值,即使其他东西发生了变化。 相反,在开发工具控制台中获取对输入元素的引用(通过右键单击、检查然后使用$0变量)允许我执行$0.value = 'foo'并且值 'foo'是显示在字段中。

因此,对于最后一个实验,我不再那么确定了。 到底跟lit有关系吗? 我都没有主意了...

这似乎是一件很常见的事情,所以我认为lit应该支持这一点,并且我在某处做错了什么......

我可以收听更改事件,然后手动设置.value属性。 但这似乎是不必要的“手动”。 那么我该如何正确地做到这一点呢?

我设法将问题简化为一个非常小的可重现示例。 我在这里写在codepen上: https://codepen.io/exhuma/pen/eYrNQJK

作为参考,这里是使用和定义组件的代码:

<!-- using the component -->
<text-field-demo></text-field-demo>
<script type="module" src="path-to-ts-file" />
// The TypeScript file to load in the HTML
// document which uses the component

import {
  LitElement,
  html,
  customElement,
  state
} from "https://cdn.skypack.dev/lit@2.3.1";

export class TextFieldDemo extends LitElement {
  // [does not work in CodePen] @state()
  data = 0;

  doIncrement() {
    // This increment should be reflected in the UI
    // even *after* a manual edit was made in
    // the text-field
    this.data += 1;
    console.log(this.data);
    this.requestUpdate();
  }

  /**
   * Update the local component state with the new value from the DOM
   * @param evt The change event
   */
  updateObject(evt) {
    this.data = Number.parseInt(evt.target.value, 10);
  }

  render() {
    return html`
      Object:
      <input type="text" value=${this.data} @change=${this.updateObject} />
      <button @click=${this.doIncrement}>Increment and log</button>
      <pre>Data in non-interactive element: ${this.data}</pre>
    `;
  }
}
customElements.define("text-field-demo", TextFieldDemo);

简短的回答

绑定到属性,而不是属性:

<input type="text" .value=${this.data} />

详细解释的长答案

HTMLInputElementvalue属性在第一次渲染时用作初始值(可用作 DOM 对象的defaultValue属性); 稍后更改value属性既不会产生任何视觉影响,也不会反映到value属性(始终与输入显示的内容同步)。 不过,它确实改变了defaultValue属性。

我没有为您做出此设计决定的确切原因,但如果您想检查输入的内容是否已被修改(el.value.== el.defaultValue) ,这将很有帮助。

另见https://github.com/lit/lit/issues/743#issuecomment-454042498

因此,要解决您的问题,请放置一个. 在您的渲染方法中的value之前(它告诉 lit 绑定到属性而不是属性):

<input type="text" .value=${this.data} />

如果您的更改处理程序所做的只是将用户输入写回您的 state,那么这已经为您完成了。

另见https://github.com/lit/lit/issues/743#issuecomment-454057588

由于这是一个非常常见的错误来源, eslint-plugin-lit (您的项目显然没有使用它)甚至对此有一个规则(另请参阅此说明)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM