最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - LitElement not updating checkbox in list - Stack Overflow

programmeradmin4浏览0评论

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);

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./edit/typescript-fylwxb

Share Improve this question edited May 3, 2019 at 1:55 dork asked May 3, 2019 at 1:36 dorkdork 4,5783 gold badges33 silver badges59 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 17

This is because of the behavior of the checked attribute. According to MDN docs:

A Boolean attribute indicating whether or not this checkbox is checked by default (when the page loads). It does not indicate whether this checkbox is currently checked: if the checkbox’s state is changed, this content attribute does not reflect the change. (Only the HTMLInputElement’s checked IDL attribute is updated.)

In fact, in your example, the checked state of the input is not being toggled by this line:

?checked=${item.isDone}

but by the native behavior of the checkbox, which also sets the checked property to true. To prove this you can try to programmatically uncheck it after clicking on it:

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

lit-html is probably reusing the input DOM node from the deleted line to render the subsequent line without creating a new one, thus keeping the checked property true.

The boolean attribute binding (?) only sets or removes the attribute. You should instead use the property binding (.) to correctly update HTMLInputElement’s checked property.

<input type="checkbox"
       value=${item.id}
       .checked=${item.isDone}
       @click=${this.toggleCheck}>
发布评论

评论列表(0)

  1. 暂无评论