【问题标题】:Svelte: using "bind:this" inside "each" blockSvelte:在“每个”块中使用“bind:this”
【发布时间】:2021-02-09 04:33:54
【问题描述】:

我想渲染一个对象数组,使用each 块。我需要能够使用 each 块内部的回调从数组中删除元素。此外,对于更复杂的 UI 交互,我需要在主应用程序中提供对 each-block 的每个组件的引用。

这是我的方法:

<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-array 中得到null-values。这是我的一种方法(打印refs-array 的each-部分应该有助于显示null-values):

<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)。如何保持引用和数据同步?

【问题讨论】:

    标签: svelte


    【解决方案1】:

    解决此问题的方法是在使用 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)
    

    【讨论】:

    猜你喜欢
    • 2021-07-23
    • 2021-07-03
    • 2021-10-03
    • 2021-09-28
    • 2020-02-01
    • 2019-10-17
    • 1970-01-01
    • 2022-01-24
    相关资源
    最近更新 更多