在Svelte可读存储数组中,如何只更新一个项目而不触及其他项目?

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

我想这个问题更多的是关于JS的sysntax,但是我有一个像这样的存储数组,这个存储数组定义了它的set方法来更新来自websockets连接的值。

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});
    }
})

在这里,我没有办法 "设置 "数组,而且不用每次更新都要声明整个数组。

javascript arrays store svelte
1个回答
0
投票

我想在你的情况下,你想保存在存储中的不是一个数组,而是一个对象,这将使这一步更容易。类似这样。

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)
    }
})

注意,这样一来,你将直接把通道作为对象的键: 所以如果一个通道已经存在,它将被更新,而不是被添加。如果它不存在,它将被添加。

因此,在你的订阅者中,你可以有这样的内容。

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

最后,考虑到这段代码每次更新都会创建一个新的对象,以避免副作用,这是常见的做法。 然而,如果你的对象中有很多数据,并且你意识到可能的影响,你可以直接添加更新单个键,而不需要每次重复对象,这是出于性能内存的考虑。

希望能帮到你!


0
投票

我认为可读存储不能解决你的问题,因为你这里没有更新方法。你为什么不试着用一个 "可读存储 "来解决你的问题呢?可写商店 而不是?它给了你一个以当前值为参数的更新函数,所以你可以做这样的事情。

    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 与工作原理的一个例子。它使用间隔来模拟webhooks功能。如果你打开控制台,你可以看到更新的存储值。


0
投票

你也可以在回调里面访问可读存储的实际值。然后你可以更新现有的数组,而不需要全部替换。

<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}
© www.soinside.com 2019 - 2024. All rights reserved.