使用自定义方法和反应值存储

问题描述 投票:0回答:1

我正在构建一个 Svelte 组件来显示一个列表,其项目可以添加到选择中。选择本身就是一家商店:

selectionStore.js

import {writable} from 'svelte/store';

function createSelectionStore() {
    const { subscribe, set, update } = writable(JSON.parse(localStorage.getItem("selection")) || {});

    function remove(selection, itemId, itemType) {...}

    function add(selection, item) {...}

    return {
        subscribe,
        remove: (itemId, itemType) => update(selection => remove(selection, itemId, itemType)),
        add: (item) => update(selection => add(selection, item)),
        toggleSelection: (item) => update(selection => {
            if (selection[item.type]?.[item.id]) {
                return remove(selection, item.id, item.type);
            }
            return add(selection, item);
        }),
        isSelected: (selection, item) => {
            return selection[item.type]?.hasOwnProperty(item.id) || false;
        },
        length: (selection, itemType) => {
            return Object.keys(selectedItems[itemType]).length ?? 0
        },
    };
}
export const selectionStore = createSelectionStore();

然后将商店导入到组件中:

RecordList.svelte

<script>
    import Record from "./Record.svelte";
    import { selectionStore } from "./selectionStore.js";
    export let records = [];

    $: selectionLength = selectionStore.length(false);
</script>

<p>Number of selected items: {selectionLength}</p>

{#if records.length !== 0}
    <div>
        {#each records as item (item.id)}
            <Record {item}/>
        {/each}
    </div>
{/if}

Record.svelte

<script>
    import { selectionStore } from './selectionStore.svelte';
    export let item;

    $: isSelected = selectionStore.isSelected(item);
</script>

<div class="item">
    {item.item}
    <button on:click={() => selectionStore.toggleSelection(item)}>
        {isSelected ? 'Remove from' : 'Add to'} selection
    </button>
</div>

我面临的问题是

isSelected
selectionLength
不是反应性的,尽管
toggleSelection()
似乎有效。我知道我没有正确构建我的商店,但我找不到正确的方法。

我尝试对其进行 REPL,但无法为商店创建 js 文件。

svelte svelte-store
1个回答
0
投票

所有应该响应的东西都需要是一个商店。
对于这些函数,您需要一个

derived
,它取决于保存选择数据的商店。

const selection = writable(...);
const { subscribe, set, update } = selection;

const isSelected = derived(selection, $selection =>
  item => $selection[item.type]?.hasOwnProperty(item.id) || false
);

...

return { subscribe, isSelected, ... }
<script>
  import { selectionStore } from './selectionStore.js';

  export let item;
  
  const { isSelected } = selectionStore; // required for accessing store via $
  $: itemSelected = $isSelected(item); // or just inline in template
</script>

REPL 示例

© www.soinside.com 2019 - 2024. All rights reserved.