English 中文(简体)
是否有可能在互换互换时有两处可观的商店?
原标题:Is it possible to have two writable stores in svelte subscribe to each other?

有一个物体,其数据与另一个物体相匹配,但它们有不同的结构。

例如,考虑这一设想:

The Team object holds the team ID as its key. The Team object contains name and users objects as its values. The users object has the user ID as its key, which doesn t overlap with user IDs from other teams.

因此,我要提出一个有所有用户的新目标。

The users object can be subscribed to by users, and modifying this should reflect changes in the Team object. Conversely, the Team object can be subscribed to by users, and modifying it should reflect changes in the users object.

How can I achieve this?

我试图在Java文本档案中利用用户功能更新每个物体,但我最后陷入了无限的 lo,失败了。

这里的例子有:

<script>
    import {writable} from "svelte/store";
    
    const teamDict = writable({})
    const userDict = writable({})

    function initTeamDict() {
        teamDict.set({
            1: {
                name: "good team",
                users: {
                    1: "James",
                    2: "Poppy",
                    48: "Hway"
                }
            },
            2: {
                name: "bad team",
                users: {
                    47: "Kelin",
                    35: "Teo",
                    24: "Ferma"
                }
            }
        })
    }

    function initUserDict() {        
        userDict.set(Object.values($teamDict).reduce((acc, team) => ({...acc, ...team[`users`]}), {}))
    }


</script>

<button on:click={initTeamDict}>init team dict</button>
<button on:click={initUserDict}>init user dict</button>

<div> {JSON.stringify($teamDict)}</div>
<div> {JSON.stringify($userDict)}</div>

<button on:click={() => $teamDict[`1`][`users`][`1`] = "top"}>this button should change userDict also </button>
<button on:click={() => $userDict[`1`] = "bottom"}>this button should change teamDict also </button>

REPL

https://svelte.dev/repl/e6570ac9ca464c15967a43c8311dcd4d?vert=4.2.8”rel=“nofollow noreferer”>https://svelte.dev/repl/e6570ac9ca464c15967a43c8311dcd4d?version=4.2.8

Edit

在@ghostmodd的答复的帮助下,我通过撰写以下法典解决了这一问题。

我复制了该物体,并修改了该物体,因为修改复制件不会引发订阅。

修改后的物体不得在订货单上提出,因此,我使用衍生物形成了一种单独的看法。

<script>
    import {derived, writable} from "svelte/store";
    import {Button} from "flowbite-svelte";

    const teamDict = writable({})
    const userDict = writable({})

    teamDict.subscribe(($$teamDict) => {
        const userDictCopy = $userDict
        for (const key in userDictCopy) {
            delete userDictCopy[key]
        }
        Object.assign(userDictCopy, Object.values($$teamDict).reduce((acc, team) => ({...acc, ...team[`users`]}), {}))
    })
    userDict.subscribe(($$userDict) => {
        const teamDictCopy = $teamDict
        for (const team of Object.values(teamDictCopy)) {
            team[`users`] = {}
        }
        for (const [userId, user] of Object.entries($$userDict)) {
            teamDictCopy[user[`team_id`]][`users`][userId] = user
        }
    })

    const storeView = derived(
        [teamDict, userDict],
        ([$teamDict, $userDict], set) => {
            set({teamDict: $teamDict, userDict: $userDict})
        }
    )

    function initTeamDict() {
        teamDict.set({
            1: {
                name: "good team",
                users: {
                    1: {
                        "name": "James",
                        "team_id": 1
                    },
                    2: {
                        "name": "Poppy",
                        "team_id": 1
                    },
                    48: {
                        "name": "Hway",
                        "team_id": 1
                    }
                }
            },
            2: {
                name: "bad team",
                users: {
                    47: {
                        "name": "Kelin",
                        "team_id": 2
                    },
                    35: {
                        "name": "Teo",
                        "team_id": 2
                    },
                    24: {
                        "name": "Ferma",
                        "team_id": 2
                    }
                }
            }
        })
    }


</script>

<Button on:click={initTeamDict}>init team dict</Button>

<div> {JSON.stringify($storeView.teamDict)}</div>
<div> {JSON.stringify($storeView.userDict)}</div>

<Button on:click={() => $teamDict[`1`][`users`][`1`][`name`] = "top"}>this button should change userDict also </Button>
<Button on:click={() => $userDict[`1`][`name`] = "bottom"}>this button should change teamDict also </Button>

REPL https://svelte.dev/repl/0b89313234b8d94a6adf38ba?version=4.2.8

问题回答

实际上,你可以做到,使用中间线derived Store。 衍生的仓库与React's useEffect hook相似。 它监督特定仓库的最新情况,并处理这些仓库。

因此,除“小组”和“用户”外,你应建立一个衍生的仓库,收集并节省最新情况。

That`s how I did it. Firstly, I created original writable stores with an empty object value.

const teamDict = writable({})
const userDict = writable({})

然后,我把中间衍生的储存放在了以前创建的实体之后。

const intermediateStore = derived(
    [teamDict, userDict],
    ([$teamDict, $userDict], set) => {
        // your handler here
    },
    {
        teamDict: {},
        userDict: {},
    }
)

注意这些论点。 第一个论点是一份可观察库存清单。 第二个论点是处理最新情况的职能。 第三个论点是衍生物储存的最初价值。

第三步是节省衍生仓库所需的数据。 因此,我写了这方面的手稿。

        // create a copy of the teamDict store just to make work more comfortable
        const teamDictCopy = {
            ...$teamDict,
        }

        // Check the userDict store for required data. Actually, you can optimize
        // this loop.
        // I use JSON.parse in aim to get rid of meta data in the store object (f. i., set, update)
        for (let userID in JSON.parse(JSON.stringify($userDict))) {
            const teamID = $teamDict[$userDict[userID].team]

            // Check if the specified team exists
            if ($teamDict[teamID]) {
                teamDictCopy[teamID].users[userID] = $userDict[userID]
            } else {
                console.log("Error! This team hasn`t been initialized yet")
                return
            }
        }

        const userDictCopy = Object.values($teamDict).reduce((acc, team) => ({...acc, ...team[`users`]}), {})

        // setting the intermediate derived state`s value
        set({
            teamDict: teamDictCopy,
            userDict: userDictCopy,
        })

Link to REPL: https://svelte.dev/repl/1966610b5c647e497918911ac1d8269?version=4.2.8

P.S.对我的英语表示歉意。 我仍在学习:3





相关问题
selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

How to fire event handlers on the link using javascript

I would like to click a link in my page using javascript. I would like to Fire event handlers on the link without navigating. How can this be done? This has to work both in firefox and Internet ...

How to Add script codes before the </body> tag ASP.NET

Heres the problem, In Masterpage, the google analytics code were pasted before the end of body tag. In ASPX page, I need to generate a script (google addItem tracker) using codebehind ClientScript ...

Clipboard access using Javascript - sans Flash?

Is there a reliable way to access the client machine s clipboard using Javascript? I continue to run into permissions issues when attempting to do this. How does Google Docs do this? Do they use ...

javascript debugging question

I have a large javascript which I didn t write but I need to use it and I m slowely going trough it trying to figure out what does it do and how, I m using alert to print out what it does but now I ...

Parsing date like twitter

I ve made a little forum and I want parse the date on newest posts like twitter, you know "posted 40 minutes ago ","posted 1 hour ago"... What s the best way ? Thanx.

热门标签