LitElement从列表中删除项目

4

当页面首次加载时,下面代码生成的删除按钮可以正常工作。但是,如果您更改了其中一个<textarea>元素中的文本,则删除按钮将不再正确工作。我该如何解决这个问题?

import { LitElement, html } from 'lit-element';

class MyElement extends LitElement {
  static get properties() {
    return {
      list: { type: Array },
    };
  }
  constructor() {
    super();
    this.list = [
      { id: "1", text: "hello" },
      { id: "2", text: "hi" },
      { id: "3", text: "cool" },
    ];
  }
  render() {
    return html`${this.list.map(item =>
        html`<textarea>${item.text}</textarea><button id="${item.id}" @click="${this.delete}">X</button>`
    )}`;
  }
  delete(event) {
    const id = event.target.id;
    this.list = this.list.filter(item => item.id !== id);
  }
}
customElements.define("my-element", MyElement);

嗯,奇怪的是列表是正确的,但显示不正确。请查看 https://stackblitz.com/edit/delete-list-element?file=my-element.js 编辑 'hi' 为 'hi there',切换到其他选项卡,然后删除。控制台中的列表是正确的,但显示不正确。 - Thad
1
实际显示的列表已更新,文本区域的内容也已更新(如果更改列表文本,则innerHtml显示更新的内容),但编辑后的文本区域的内容在视觉上未更新。这个错误也会出现在<input type=text>元素中。就像浏览器记住哪个输入框被编辑并在更新后保持其内容不变一样。 - grohjy
1
尝试使用repeat指令 - abraham
我同意@grohjy的说法,这个列表确实是更新了,并且元素也被重新渲染了。你可以通过检查看到它,只是浏览器在删除一个文本区域后仍然保持前两个文本区域可见。另一个证明它是某种“缓存”的事实是,重新渲染后您仍然可以看到您键入的内容,但由于您没有在每次呈现时更新this.list,它应该使用初始值进行呈现(如果您进行检查,它确实这样做)。 - mishu
1个回答

10

我不确定具体的原因,但我认为这与lit-html在渲染一个比之前少项目的列表时决定删除哪些DOM元素有关。解决方法是使用repeat指令。它的第二个参数是一个函数,帮助lit-html识别数组中哪些项对应哪些DOM元素:

import { repeat } from 'lit-html/directives/repeat.js'

// ...
render(){
  return html`
    ${repeat(this.list, item => item.id,
      item => html`<textarea>${item.text}</textarea><button id="${item.id}" @click="${this.delete}">X</button><br>`
    )}
  `;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接