我最近开始研究Svelte,并希望创建一个名为SelectorTable
的组件,它允许我通过单击它们来选择表的行。选定的行应该以不同的颜色突出显示。
我试着在class directive
中使用构建。
<script lang="ts">
type ObjectKey = keyof any;
export let data: any[] = [];
export let key = 'id' as ObjectKey;
let selected: Set<ObjectKey> = new Set<ObjectKey>();
function toggle(id: ObjectKey) {
if (selected.has(id)) {
selected.delete(id);
} else {
selected.add(id)
}
console.log(selected)
console.log(selected.has(id))
}
</script>
<table>
<thead>
<tr>
{#each Object.keys(data[0]) as heading}
<th>{heading}</th>
{/each}
</tr>
</thead>
<tbody>
{#each Object.values(data) as row}
<tr class:tr-selected={selected.has(row[key])} on:click={() => {toggle(row[key])}}>
{#each Object.values(row) as cell}
<td>{cell}</td>
{/each}
</tr>
{/each}
</tbody>
</table>
<style>
table, th, td {
border: 1px solid;
border-collapse: collapse;
margin-bottom: 10px;
}
tr:hover {
background-color: red;
cursor: pointer;
}
.tr-selected {
background-color: greenyellow;
}
</style>
on:click
函数toggle
可以正确地添加或删除选定的键。我的问题是,所选行的背景颜色没有改变,即使selected.has(row[key]) == true
。下面是使用键1
单击一行两次时的控制台输出。
> Set(1) {1} ------- SelectorTable.svelte:14
> true ------------- SelectorTable.svelte:15
> Set(0) {size: 0} - SelectorTable.svelte:14
> false ------------ SelectorTable.svelte:15
首先将关键点添加到选定的集合中,然后再次将其删除。
那么,如果selected.has(row[key])
的输出为true,为什么class指令不起作用,行的颜色也不改变?
2条答案
按热度按时间kpbwa7wx1#
React性是基于赋值的,所以如果你使用像
Set
这样的通过函数修改的东西,你可以在修改后添加一个虚拟赋值,以在使用集合的任何地方触发更新:nfg76nw02#
我找到了解决办法。不知道是否有更好的,但这一个工作。
在尝试了一段时间后,我意识到Svelte没有检查class指令中的
selected.has(row[key])
,因此没有重新呈现该行。然后,我尝试通过将selected
设置到svelteskey
逻辑块中,但它仍然不工作。最后,我添加了一个新的布尔变量
update
,我在key
块中引用它,每次调用函数toggle
时,update都会被翻转。如果我错了请纠正我。
我假设这种行为的原因是JS/TS通过引用传递对象和函数,如
selected
或toggle
,并通过值传递原始变量,如int或布尔值。key
状态的Sveltes文档“当表达式的值更改时,键块将销毁并重新创建其内容。”
这可以解释为什么使用
selected
时该行没有重新呈现。因为它是通过引用传递的,引用也是基本类型,而且因为只有引用后面的值发生了变化,而不是引用本身,所以Svelte不能识别变化,因此不会重新呈现。在类指令的文档中没有特别说明这种行为,但假设它是类似的是保存的。