LitElement 不更新列表中的复选框
LitElement not updating checkbox in list
我有一个简单的清单,每个项目都有一个删除按钮。当我选中第一个项目然后将其删除时,列表会更新,删除该项目,但会选中下一个项目的复选框。下一项的属性是正确的。
这是我的代码:
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);
这是因为 checked
属性的行为。根据 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.)
事实上,在您的示例中,输入的选中状态未被此行切换:
?checked=${item.isDone}
但是通过复选框的本机行为,它还将 checked
属性 设置为 true
。为了证明这一点,您可以尝试在单击它后以编程方式取消选中它:
// This won't have any effect if yourInputElement.checked is true
yourInputElement.removeAttribute('checked');
lit-html 可能正在重用已删除行中的输入 DOM 节点来呈现后续行而不创建新行,从而使选中的 属性 保持为真。
布尔属性绑定 (?
) 仅设置或删除 属性。您应该改为使用 属性 绑定 (.
) 来正确更新 HTMLInputElement
的 checked
属性.
<input type="checkbox"
value=${item.id}
.checked=${item.isDone}
@click=${this.toggleCheck}>
我有一个简单的清单,每个项目都有一个删除按钮。当我选中第一个项目然后将其删除时,列表会更新,删除该项目,但会选中下一个项目的复选框。下一项的属性是正确的。
这是我的代码:
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);
这是因为 checked
属性的行为。根据 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
’schecked
IDL attribute is updated.)
事实上,在您的示例中,输入的选中状态未被此行切换:
?checked=${item.isDone}
但是通过复选框的本机行为,它还将 checked
属性 设置为 true
。为了证明这一点,您可以尝试在单击它后以编程方式取消选中它:
// This won't have any effect if yourInputElement.checked is true
yourInputElement.removeAttribute('checked');
lit-html 可能正在重用已删除行中的输入 DOM 节点来呈现后续行而不创建新行,从而使选中的 属性 保持为真。
布尔属性绑定 (?
) 仅设置或删除 属性。您应该改为使用 属性 绑定 (.
) 来正确更新 HTMLInputElement
的 checked
属性.
<input type="checkbox"
value=${item.id}
.checked=${item.isDone}
@click=${this.toggleCheck}>