我有一个父组件 (
List
),它显示子组件列表 (Block
)。嵌套块有一个按钮,允许用户将它们添加/删除到选择中。
列表组件还包含一个表格,列出了所有选定的块:用户也可以在那里取消选择块。
我的问题是,当从
table#selection
中取消选择时,isSelected
变量显然没有更新
如何动态更新Block组件内的
isSelected
变量?我处理逻辑错了吗?
List.svelte
<script>
import Block from './Block.svelte';
export let blocks = [];
let selection = {};
let isBlockSelected = (block) => selection.hasOwnProperty(block.id);
function removeFromSelection(blockId) {
const { [blockId]: _, ...rest } = selection;
selection = rest;
// 🛑 TODO make block aware that it has been unselected
}
function addToSelection(block) {
selection = { ...selection, [block.id]: block };
}
function handleToggleSelection(event) {
const { block } = event.detail;
if (!isBlockSelected(block)) {
addToSelection(block);
} else {
removeFromSelection(block.id);
}
}
</script>
<div>
{#each blocks as block (block.id)}
<Block {block} on:toggleSelection={handleToggleSelection} isSelected={isBlockSelected(block)}/>
{/each}
</div>
<table id="selection">
<tbody>
{#each Object.entries(selection) as [id, meta]}
<tr>
<td>
<a href="/page/{id}" target="_blank">{meta.title}</a>
<button class="delete" aria-label="close" on:click={() => removeFromSelection(id)}></button>
</td>
</tr>
{/each}
</tbody>
</table>
Block.svelte
<script>
import {createEventDispatcher} from "svelte";
export let block;
export let isSelected = false;
const dispatch = createEventDispatcher();
function toggleSelection(block) {
dispatch('toggleSelection', { block });
isSelected = !isSelected
}
</script>
<div>
{block.title}
<button on:click={() => toggleSelection(block)}>
{#if isSelected}
Remove from selection
{:else}
Add to selection
{/if}
</button>
</div>
制作
isBlockSelected(block)
当
selection
更改时进行更新,或者将其作为参数添加到声明和所有调用中
const isBlockSelected = (block, selection) => selection.hasOwnProperty(block.id);
或使声明具有反应性
$: isBlockSelected = (block) => selection.hasOwnProperty(block.id);