Angular Signals 中 linkedSignal 与 computed 的选择指南
问题分析
在 Angular Signals 中管理状态时,开发者常面临选择 computed
还是 linkedSignal
的困惑。核心问题在于:当派生状态需要本地修改能力时(如默认选择选项的默认值),如何同时保持与源信号的自动同步。
传统方案的局限性
typescript
// 使用 computed 的典型示例
const shippingOptions = signal(['Ground', 'Air', 'Sea']);
const selectedOption = computed(() => shippingOptions()[0]);
以上方案存在两大问题:
- 无法本地更新:
selectedOption
是只读状态 - 自动重置缺失:当选项改变时,当前选定项无法智能更新
linkedSignal 的核心优势
基本概念
linkedSignal
是 Angular Signals 中的特殊信号类型:
- 继承
computed
自动计算的能力 - 添加了
WritableSignal
的本地写入能力 - 提供源信号变化时的重置逻辑控制
与 computed 的本质区别
特性 | computed | linkedSignal |
---|---|---|
写入能力 | 只读 | ⚙️ 可读写 |
依赖追踪 | ✅ | ✅ |
重置逻辑 | ❌ | ✅ |
前值访问 | ❌ | ✅ |
具体应用场景
场景一:简单默认值绑定
typescript
const shippingOptions = signal(['Ground', 'Air', 'Sea']);
// 默认绑定第一个选项
const selectedOption = linkedSignal(() => shippingOptions()[0]);
// 更新选项同时保持选中项有效
shippingOptions.set(['Rail', 'Drone', 'Sea']);
// 此时 selectedOption() 自动变为 'Rail'
场景二:智能选中项维护
typescript
const options = signal(['A', 'B', 'C']);
const selection = linkedSignal({
source: options,
computation: (currentOptions, previousSelection) => {
// 若之前选择项仍存在,保留它
if (previousSelection && currentOptions.includes(previousSelection.value)) {
return previousSelection.value;
}
// 否则返回第一个选项
return currentOptions[0];
}
});
// 用户可手动更改选择
selection.set('B');
// 当删除选中项时自动重置
options.set(['A', 'C']);
// selection() 自动变为 'A'
场景三:组件输入状态同步
typescript
@Component({...})
export class SelectorComponent {
// 输入信号(外部传入)
externalOptions = input.required({transform: array});
// 本地可选状态(可内部修改)
localSelection = linkedSignal(() => this.externalOptions()[0]);
// 组件内部更新选择
updateSelection(option: string) {
this.localSelection.set(option);
}
}
最佳实践建议
何时选择 computed
- 纯计算属性(如
total = computed(() => prices().reduce(...))
) - 不需要本地写入的派生状态
- 简单依赖关系无重置需求
何时选择 linkedSignal
- 需本地修改的派生状态(如表单选择)
- 源数据变化时需要智能重置
- 需同时追踪源变化和人工修改
性能优化注意事项
- 避免过度重置:复杂的
computation
函数会增加性能开销 - 按需选择模式:typescript
// 简单模式:轻量级但灵活性低 linkedSignal(() => source()[0]); // 高级模式:功能强但有开销 linkedSignal({ source: multipleSources, computation: (vals, prev) => { ... } });
- 注意信号依赖链:深层嵌套的
linkedSignal
可能影响变更检测效率
总结
linkedSignal
解决了 Angular 信号系统中派生状态可写性与源同步的核心痛点:
- 优先使用
computed
:适用于无本地修改需求的纯计算场景 - 智能选择
linkedSignal
:当需要:- ✏️ 修改计算的默认值
- 🔄 源变更时自动重置状态
- ⚖️ 同步维护外部输入和本地状态
其特有的computation
函数提供了强大的重置策略控制能力,使其成为处理动态数据源(如可修改选项列表)的理想选择。