簡體   English   中英

在 Svelte 可讀存儲數組中,如何只更新一個項目而不觸及其他項目?

[英]In a Svelte readable store array, How can I update only one item without touching the others?

我想這個問題更多地是關於 JS sysntax,但我有一個這樣的存儲數組:

export const store = readable( {id: 0, value: 0} , set => {
    let socket = new WebSocket("ws://localhost:65432");
    socket.onmessage = function (event) {
        var data = JSON.parse(event.data);
        set({id: 0, value: data});
    }
})

商店定義了它的 set 方法來更新來自 websockets 連接的值。 我怎么能做同樣的事情,但使用存儲數組? 就像是:

arr = [];
for(i=0; i<numberOfItems; i++) {
    arr = [...arr,{id: i, value: 0}];
}

export const store = readable( [{arr}] , set => {
    let socket = new WebSocket("ws://localhost:65432");
    socket.onmessage = function (event) {
        var data = JSON.parse(event.data);
        var channel = data.channel;
        set({id: data.channel, value: data.value});
    }
})

這是我無法“設置”數組的地方,並且不必在每次更新時聲明整個數組。

我認為在您的情況下,您要保存在商店中的不是數組,而是 object,這會使這一步更容易。 就像是:

export const store = readable({} , set => {
    let channels = {};
    let socket = new WebSocket("ws://localhost:65432");
    socket.onmessage = function ({data}) {
        let { channel, value } = JSON.parse(data);

        // update `channels`
        channels = {...channels, [channel]: value };

        // set the new `channels` as store value
        set(channels)
    }
})

請注意,通過這種方式,您將直接將頻道作為 object 的鍵:因此,如果頻道已經存在,它將被更新而不是添加。 如果它不存在,它將被添加。

因此,在您的訂閱者中,您可以擁有以下內容:

store.subscribe(channels => {
  for (let [channel, value] of Object.entries(channels)) {
    console.log(`channel ${channel} received ${value}`);
  }
});

最后一點,考慮到這段代碼每次更新都會創建一個新的 object 以避免副作用,這是常見的做法。 但是,如果您在 object 中有大量數據並且您知道可能的含義,您可以只添加/更新單個密鑰,而無需每次都復制 object,出於性能/ZCD69B4957F06CD818D7BF3D61980E 的原因。

希望能幫助到你!

我認為可讀存儲不會解決您的問題,因為您這里沒有更新方法。 您為什么不嘗試使用可寫存儲呢? 它以當前值作為參數為您提供更新 function,因此您可以執行以下操作:

    let socket = new WebSocket("ws://localhost:65432");
    socket.onmessage = function(event) {
      var data = JSON.parse(event.data);
      var channel = data.channel;
      store.update(n => [...n, { id: data.channel, value: data.value }]);
    };

這是一個REPL ,其中有一個如何工作的示例。 它使用間隔來模擬 webhook 功能。 如果您打開控制台,您可以看到更新后的存儲值。

您也可以在回調中訪問可讀存儲的實際值。 然后您可以更新現有數組而不替換全部:

<script>
    import {readable} from 'svelte/store'

    let intervalHandle
    const arr = new readable(['Start'], (set) => {
        intervalHandle = setInterval(() => {
            set([...$arr, 'Another value'])     
        }, 1000)
    })

</script>

<h1>Readable demo</h1>
<button on:click={() => clearInterval(intervalHandle)}>Stop it</button>
{#each $arr as item}
<div>{item}</div>
{/each}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM