我有一个节点数组,在我的例子中,这些节点是包含一些数据的对象,包括id
。我只想显示活动节点,它是通过比较节点ID和活动节点ID找到的。我可以成功地使用它:
let active_node_id: string;
active_node_stream.subscribe((value) => (active_node_id = value));
...
{#each nodes as node (node.id)}
{#if node.id === active_node_id}
<Node {...node} />
{/if}
{/each}
然而,这种循环遍历所有节点只显示一个节点的模式似乎是错误的。有没有更好的办法?
我想尝试使用Svelte的React式声明,以便在找到活动节点后停止循环,如下所示:
$: active_node_data = nodes.find(n => n.id === active_node_id)
...
<Node {...active_node_data} />
但这给了我以下错误(我使用的是TypeScript --当我试图重现它时,它似乎是work fine with JavaScript):
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'length')
at $$self.$$.update
我不知道为什么会发生这个错误,因为active_node_id
应该总是匹配节点的ID。当这个错误发生时,我已经记录了节点值和active_node_id
,它们确实匹配…
无论如何,这种方法并不比each
和if
方法好得多。有没有更好的方法保持苗条
2条答案
按热度按时间enxuqcxy1#
我认为被动分配确实是完成这类任务的最好方式。
代码中的问题以及typescript对它不满意的原因是,如果没有找到节点,
find
可能会返回undefined。MDN docs -> find:返回数组中 predicate 为true的第一个元素的值,否则返回undefined。
所以只要提供一个默认值,以防它是未定义的,像这样的东西就可以做到这一点:
xiozqbni2#
我和我的熟人yuanchuan聊了聊这件事。他建议使用
Map
与if
配对,这样感觉更好。首先,你需要建立一个Map(我在我的节点数据所在的地方做了这个):
然后,您可以导入该Map并使用它来查找当前活动节点:
因此,使用Svelte的React性是一种方法,但也有更好的方法来做到这一点,如使用Map。
然而,上面提供的方法防止了活动节点发生变化时的转换(在我的例子中,我隐藏了非活动节点)。这是因为上面的方法使用了节点的单个示例,仅切换出数据,而不是真正地将元素移入或移出。因此,我坚持使用原来的方法,使用
each
和if
。旁注:原来
Cannot read properties of undefined (reading 'length')
错误是来自我的Node
组件内部,当某个属性没有被传入某些节点时。它是由这些线引起的:我希望选项总是有一个长度(至少是0),有时不是
undefined
。$: is_choice = options?.length !== 0;
也抛出了错误,这令人惊讶。但是$: is_choice = options ? options.length !== 0 : false;
工作正常。我不明白为什么可选的链接方法不起作用(也许是编译器的问题?))我也不知道为什么这不是each
方法的问题。