Svelte:在 "each" 块中使用 "bind:this"
Svelte: using "bind:this" inside "each" block
我想渲染一组对象,使用 each
块。我需要能够使用 each
块内部的回调从数组中删除元素。此外,对于更复杂的 UI 交互,我需要在主应用程序中提供对 each
块的每个组件的引用。
这是我的方法:
<script>
let items = [{text: "one"}, {text: "two"}];
function deleteItem(i) {
items.splice(i, 1);
items = items;
}
</script>
{#each items as item, i}
<button bind:this={items[i].ref} on:click={() => deleteItem(i)} >
{item.text}
</button>
<p />
{/each}
可以理解,这会导致item[i] is undefined
等错误,因为在处理items
的拼接时,bind:this
已经无法正常清理了
我试图通过将组件引用移动到一个单独的数组来解决这个问题。但是无论我尝试什么,我都无法使引用数组和对象数组同步:每当处理 deleteItem()
时,我最终都会在 refs
- 中得到 null
-values大批。这是我的一种方法(打印 refs
数组的 each
部分应该有助于显示 null
值):
<script>
import {tick } from "svelte";
let items = [{text: "one", id: 1}, {text: "two", id:2}];
let refs = [];
async function deleteItem(i) {
items.splice(i, 1);
await tick();
refs.splice(i, 1);
items = items;
console.log(refs);
}
</script>
{#each items as item, i (item.id)}
<button on:click={async () => deleteItem(i)} bind:this={refs[i]}>
{item.text}
</button>
<p />
{/each}
{#each refs as ref}
{ref}
<p />
{/each}
我尝试使用和不使用 tick()
,尝试在不同的地方插入 tick()
,使用和不使用 async
,以及使用和不使用 (item.id)
在每个块中.如何使引用和数据保持同步?
解决此问题的方法是在使用前清理 refs
数组:
<script>
let items = [...]
let _refs = []
$: refs = _refs.filter(Boolean)
</script>
<button bind:this={_refs[i]}></button>
使用此技术,您仍将在原始 _refs 数组中拥有 null
值,但复制版本 (refs) 会很干净。
另一种方法是将元素绑定到项目本身,但如果您也在其他地方使用该数据,则可能不需要这样做:
<button bind:this={item.ref}>
(请注意,这仍然会出错,因为绑定元素在切片过程中消失,但仅通过赋值处理,您可以通过使用过滤器语句将切片和赋值合二为一来解决这个问题)
items = items.filter((item, idx) => idx != i)
我想渲染一组对象,使用 each
块。我需要能够使用 each
块内部的回调从数组中删除元素。此外,对于更复杂的 UI 交互,我需要在主应用程序中提供对 each
块的每个组件的引用。
这是我的方法:
<script>
let items = [{text: "one"}, {text: "two"}];
function deleteItem(i) {
items.splice(i, 1);
items = items;
}
</script>
{#each items as item, i}
<button bind:this={items[i].ref} on:click={() => deleteItem(i)} >
{item.text}
</button>
<p />
{/each}
可以理解,这会导致item[i] is undefined
等错误,因为在处理items
的拼接时,bind:this
已经无法正常清理了
我试图通过将组件引用移动到一个单独的数组来解决这个问题。但是无论我尝试什么,我都无法使引用数组和对象数组同步:每当处理 deleteItem()
时,我最终都会在 refs
- 中得到 null
-values大批。这是我的一种方法(打印 refs
数组的 each
部分应该有助于显示 null
值):
<script>
import {tick } from "svelte";
let items = [{text: "one", id: 1}, {text: "two", id:2}];
let refs = [];
async function deleteItem(i) {
items.splice(i, 1);
await tick();
refs.splice(i, 1);
items = items;
console.log(refs);
}
</script>
{#each items as item, i (item.id)}
<button on:click={async () => deleteItem(i)} bind:this={refs[i]}>
{item.text}
</button>
<p />
{/each}
{#each refs as ref}
{ref}
<p />
{/each}
我尝试使用和不使用 tick()
,尝试在不同的地方插入 tick()
,使用和不使用 async
,以及使用和不使用 (item.id)
在每个块中.如何使引用和数据保持同步?
解决此问题的方法是在使用前清理 refs
数组:
<script>
let items = [...]
let _refs = []
$: refs = _refs.filter(Boolean)
</script>
<button bind:this={_refs[i]}></button>
使用此技术,您仍将在原始 _refs 数组中拥有 null
值,但复制版本 (refs) 会很干净。
另一种方法是将元素绑定到项目本身,但如果您也在其他地方使用该数据,则可能不需要这样做:
<button bind:this={item.ref}>
(请注意,这仍然会出错,因为绑定元素在切片过程中消失,但仅通过赋值处理,您可以通过使用过滤器语句将切片和赋值合二为一来解决这个问题)
items = items.filter((item, idx) => idx != i)