我刚刚从 React(+Redux) 切换到 Svelte,遇到了很多我自己无法解决的问题。主要的一个是绑定深层嵌套的对象
假设我们得到了一些类似于@hgl的数据结构如何将Svelte存储与树状嵌套对象一起使用?。由于@rixo的回答,我了解了如何在单个页面上绑定文件夹和文件组件,当我一次性全部支付并且没有路由时。但是,如果我想为每个文件夹创建专用页面并通过某些
id
访问它(让我们将 name
属性视为 id
,因为它在给定模型中是唯一的),例如:
UPD这是原始问题的REPL
所以我想将不是根,而是嵌套对象绑定到我的页面标签。我的想法:
我可以尝试在我的页面中使用
$
制作一个计算道具,例如:
// ./src/folders/[id]/+page.svelte
<script lang="ts">
const urlParams = new URLSearchParams(window.location.search);
const id = urlParams.get("id");
import { root } from './stores.js'
$: thisFolder = $root.find((f) => f.name === id) // root level search
?? $root.map((pf) => pf.files?.find((f) => f.name === id)).find((f) => f) // 2nd level search, might continue if needed...
if (!thisFolder) {
eror(404, { message: "folder not found", });
}
</script>
<div>
<span>Folder name: </span>
<input bind:value={thisFolder.name}/> // !!! binding here would not work
</div>
但这行不通,我猜那是因为我们在这里不使用相同的变量,而是使用计算出来的变量。它会对商店中的更改做出反应,但不会将其更改传回商店,如果我错了,请纠正我。 UPD这是REPL
另一种选择是创建派生存储,其中我将传递
id
并获取适当的文件夹,但据我所知派生存储不可绑定,而且我不知道如何将 id
参数传递给派生店铺。 UPD这是REPL
我的第三个方法是监听输入的变化并更新对象
on:change
,但我想知道这是否可以仅通过绑定来完成(这也是我在React中执行此操作的方式,所以对我来说看起来不是反应性的)
另一种方法是使对象尽可能简单,因此每个 URL 重定向加载仅对应于
id
文件夹,但这也就像我在反应中所做的那样,这也不太适合我的应用程序
似乎我一周前在 SO 上看到了我的斗争的相关实现,但此后找不到该主题
UPD添加了一些REPL,看起来第一种方法是正确的,稍后将检查并更新问题
这就是您创建所需的派生商店的方法。
<script>
import { derived } from 'svelte/store';
import { root } from './stores.js'
import Folder from "./Folder.svelte";
function findFolder(root, id) {
let target = root.find(child => child.name === id);
if (target) return target;
return root.reduce((found, child) => {
if (found) return found;
if (child.type === 'folder') {
return findFolder(child.files, id);
}
return null;
}, null)
}
const specificFolder = id => derived(root, $root => findFolder($root, id))
const goatsFolder = specificFolder(id);
const id = "Goats"
</script>
<span>Goats folder</span>
<Folder files={$goatsFolder.files} expanded={true} />
<div>{JSON.stringify($goatsFolder)}</div>
<br />
<span>Complete store</span>
<Folder files={$root} expanded={true} />
<div>{JSON.stringify($root)}</div>