3

I have a simple check list with a delete button for each item. When I check the first item and then delete it, the list updates, deleting the item, but the check box of the next item is checked. The properties of the next item are correct.

Here's my code:

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

class CheckList extends LitElement {
  static get properties() {
    return {
      items: { type: Array },
    };
  }

  constructor() {
    super();
    this.items = [
      {
        id: 1,
        text: 'Item 1',
        isDone: false,
      },
      {
        id: 2,
        text: 'Item 2',
        isDone: false,
      },
    ];

    this.toggleCheck = this.toggleCheck.bind(this);
    this.deleteItem = this.deleteItem.bind(this);
  }

  render() {
    return html`
      <ul>
        ${this.items.map(item => html`
          <li>
            <input
              type="checkbox"
              value=${item.id}
              ?checked=${item.isDone}
              @click=${this.toggleCheck}
            >
            ${item.text}
            <button @click=${this.deleteItem}>X</button>
          </li>
        `)}
      </ul>
    `;
  }

  toggleCheck(e) {
    const id = Number(e.target.value);

    this.items = this.items.map(item => {
      if (item.id === id) {
        item.isDone = !item.isDone;
      }

      return item;
    });
  }

  deleteItem(e) {
    const id = Number(e.target.parentNode.querySelector('input').value);

    this.items = this.items.filter(item => item.id !== id);
  }
}

customElements.define('check-list', CheckList);

https://stackblitz.com/edit/typescript-fylwxb

4

1 回答 1

5

这是因为checked属性的行为。根据 MDN文档

一个布尔属性,指示是否默认选中此复选框(当页面加载时)。它不表示当前是否选中了此复选框如果复选框的状态发生更改,则此内容属性不会反映更改。(仅更新HTMLInputElementcheckedIDL 属性。)

实际上,在您的示例中,输入的检查状态没有被此行切换:

?checked=${item.isDone}

但是通过复选框的本机行为,它也将checked 属性设置为true. 为了证明这一点,您可以在单击它后尝试以编程方式取消选中它:

// This won't have any effect if yourInputElement.checked is true
yourInputElement.removeAttribute('checked');

lit-html 可能正在重用已删除行中的输入 DOM 节点来渲染后续行而不创建新行,从而保持选中的属性为真。

布尔属性 binding( ?) 只设置或删除属性。您应该改用属性绑定 ( .) 来正确更新HTMLInputElementchecked 属性

<input type="checkbox"
       value=${item.id}
       .checked=${item.isDone}
       @click=${this.toggleCheck}>
于 2019-05-05T17:44:17.033 回答