如何在 vanilla-typescript todo 应用程序中设置删除项目按钮
How to set up remove item buttons in vanilla-typescript todo app
我正在使用 vanilla typescript 创建一个基本的待办事项列表应用程序。将按钮附加到每个列表项后,我希望在用户单击特定列表项上的按钮时删除这些项目。为执行此操作,我尝试在 index.ts 中添加第二个 addEventListener 方法来监听移除按钮点击,然后移除父元素的子元素。我的 addEventListener 方法如下所示:
listItemBtn.addEventListener("click", (e: Event) => {
const element = e.target as HTMLUListElement;
element.removeChild(element);
});
但是,我不断在控制台中收到一条错误消息,提示“未捕获的类型错误:无法读取 属性 'addEventListener' of null”。我不确定为什么我不能将 .addEventListener 附加到 listItemBtn 而没有错误。知道如何解决这个问题吗?
这是一个link到CodeSandBox中的项目:https://codesandbox.io/s/vanilla-typescript-forked-xnnf4
您正在寻找 listItemBtn
之前的内容。如果你添加这一行
document.querySelectorAll("#listItemBtn").forEach(console.log);
在 form.addEventListener
的末尾,您将开始看到它填充了元素。
此代码中有很多地方需要更改。使用 as
时要小心,因为它可以防止 Typescript 看到潜在的运行时错误,比如元素可能是 null
.
您的问题是如何设置删除按钮,所以我实际上认为 querySelectorAll
不是正确的方法。我会在您创建 btn
的位置添加侦听器 。那时您已经将 button
元素作为变量。
你的监听函数本身有问题。同样,您在 const element = e.target as HTMLUListElement;
中遇到了麻烦的 as
,因为目标是 button
,而不是 li
。
element.removeChild(element)
是错误的,因为您需要在父对象上调用 removeChild
,例如 parent.removeChild(child)
。您可以看起来像 element.parentElement
(可能是 null
)。由于我们将此函数移动到 ListTemplate
中,因此我们可以访问父 li
变量。我们要删除的元素是 ul
中的 li
。所以实际上我们的 e.target
即 btn
并不是很有用。
在 ListTemplate
的 render
方法中,执行以下操作:
btn.addEventListener("click", () => {
this.container.removeChild(li);
});
如评论中所述,您不应设置不唯一的 id
。您可以使用 className
代替:
btn.className = "listItemBtn";
但您只需要它来设计样式。我们不再在任何地方查询此元素。
您可以清理 form
提交侦听器。没有理由创建一个变量然后分配它。直接赋值就行了。这也消除了手动指定类型的需要,因为根据您设置给变量的值可以知道类型。
form.addEventListener("submit", (e) => {
e.preventDefault();
const value = listItem.value;
const doc = new ListItem(value);
list.render(doc, value, "start");
});
我正在使用 vanilla typescript 创建一个基本的待办事项列表应用程序。将按钮附加到每个列表项后,我希望在用户单击特定列表项上的按钮时删除这些项目。为执行此操作,我尝试在 index.ts 中添加第二个 addEventListener 方法来监听移除按钮点击,然后移除父元素的子元素。我的 addEventListener 方法如下所示:
listItemBtn.addEventListener("click", (e: Event) => {
const element = e.target as HTMLUListElement;
element.removeChild(element);
});
但是,我不断在控制台中收到一条错误消息,提示“未捕获的类型错误:无法读取 属性 'addEventListener' of null”。我不确定为什么我不能将 .addEventListener 附加到 listItemBtn 而没有错误。知道如何解决这个问题吗?
这是一个link到CodeSandBox中的项目:https://codesandbox.io/s/vanilla-typescript-forked-xnnf4
您正在寻找 listItemBtn
之前的内容。如果你添加这一行
document.querySelectorAll("#listItemBtn").forEach(console.log);
在 form.addEventListener
的末尾,您将开始看到它填充了元素。
此代码中有很多地方需要更改。使用 as
时要小心,因为它可以防止 Typescript 看到潜在的运行时错误,比如元素可能是 null
.
您的问题是如何设置删除按钮,所以我实际上认为 querySelectorAll
不是正确的方法。我会在您创建 btn
的位置添加侦听器 。那时您已经将 button
元素作为变量。
你的监听函数本身有问题。同样,您在 const element = e.target as HTMLUListElement;
中遇到了麻烦的 as
,因为目标是 button
,而不是 li
。
element.removeChild(element)
是错误的,因为您需要在父对象上调用 removeChild
,例如 parent.removeChild(child)
。您可以看起来像 element.parentElement
(可能是 null
)。由于我们将此函数移动到 ListTemplate
中,因此我们可以访问父 li
变量。我们要删除的元素是 ul
中的 li
。所以实际上我们的 e.target
即 btn
并不是很有用。
在 ListTemplate
的 render
方法中,执行以下操作:
btn.addEventListener("click", () => {
this.container.removeChild(li);
});
如评论中所述,您不应设置不唯一的 id
。您可以使用 className
代替:
btn.className = "listItemBtn";
但您只需要它来设计样式。我们不再在任何地方查询此元素。
您可以清理 form
提交侦听器。没有理由创建一个变量然后分配它。直接赋值就行了。这也消除了手动指定类型的需要,因为根据您设置给变量的值可以知道类型。
form.addEventListener("submit", (e) => {
e.preventDefault();
const value = listItem.value;
const doc = new ListItem(value);
list.render(doc, value, "start");
});