[英]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.