Runtime API / Method

FlamoInstance.reconcileChildren

用传入的完整列表更新父 Instance 下手动添加的子 Instance:可复用的保留,缺少的新增,未列出的移除;更新失败时全部恢复原状。

使用说明

声明完整目标树

reconcileChildren(specs) 接收的不是增量 patch,而是当前父 Instance 完整的手动 child 目标集合。未出现在新列表中的手动 child 会被移除;传入空数组会清空手动 children,Slot 运行时拥有的 child 不包含在这份列表中。

const specs = rows.map(row => ({
key: `row:${row.id}`,
ref: resultRowRef,
parentKey: null,
mount: { kind: 'root' },
props: { row, selected: row.id === selectedId },
statePolicy: 'preserve',
}));
const receipt = await resultList.reconcileChildren(specs, {
latestWins: true,
timeoutMs: 10_000,
});
if (receipt.status !== 'committed') {
console.error(receipt.error);
} else {
console.log('mounted', receipt.mounted);
console.log('reused', receipt.reused);
console.log('removed', receipt.removed);
}

构造嵌套层级

parentKey 引用同一份 specs 中另一个 child 的 key:

await panel.reconcileChildren([
{
key: 'toolbar',
artifact: Toolbar(),
parentKey: null,
mount: { kind: 'root' },
},
{
key: 'submit',
artifact: Button({ label: '提交' }),
parentKey: 'toolbar',
mount: { kind: 'slot', slotId: 'actions', outletId: 'primary' },
},
]);

协调规则:

  • key 必须在整份列表中唯一,parentKey 必须存在且不能形成循环;
  • 相同 key、相同 exact ref / Artifact object / Instance 且 statePolicy !== 'reset' 时复用原 child;上例使用 exact ref,因此重新生成 specs 不会破坏 row identity;
  • 默认 latest-wins,新 transaction 会 supersede 同一父级尚未提交的旧 transaction;
  • prepare 或 commit 失败时返回非 committed receipt,并恢复调用前的手动 child specs;
  • mounted、reused、removed 中记录的是 Instance id,不是 child key。

这是运行态协调接口。需要生成可持久化的新组件时,将相同 key / parentKey 结构写入 Composition IR。

参数

specsreadonly RuntimeChildSpec[]
optionsReconcileRuntimeChildrenOptions