Knockout.js计算可观察对象为何被立即销毁?
Knockout.js 带读写方法的computed被立即销毁的原因及解决办法
核心原因
Knockout.js 的计算可观察对象(computed)默认启用自动清理机制:当一个computed没有任何活跃的订阅者(包括UI绑定、手动订阅、或被其他observable/computed依赖)时,Knockout会自动将其标记为已销毁(isDisposed = true)。
你的场景中,computed的read函数依赖的是普通变量而非observable,Knockout无法追踪到任何对这个computed的依赖关联,所以在创建完成后,它会判定这个computed没有被任何地方使用,立即触发自动销毁。而当依赖改为observable时,computed会被加入到该observable的依赖列表中,相当于有了“被引用”的标记,因此不会被自动清理。
解决办法
针对你需要与数据库等外部资源交互、无需将依赖设为observable的场景,有两种常用方案:
1. 给computed添加一个永久订阅
手动添加一个空的订阅函数,让Knockout认为这个computed有活跃的订阅者,避免被自动销毁:
let dbBackedValue = 0; // 模拟数据库存储的值 const myComputed = ko.computed({ read: () => { // 模拟从数据库读取 return dbBackedValue; }, write: (newValue) => { // 模拟写入数据库 dbBackedValue = newValue; // 手动触发变更通知,确保订阅者能感知到值更新 myComputed.notifySubscribers(newValue); } }); // 添加空订阅,阻止自动销毁 myComputed.subscribe(() => {});
2. 禁用自动销毁机制
在创建computed时,通过disposeWhen选项设置为永远不自动销毁:
let dbBackedValue = 0; const myComputed = ko.computed({ read: () => dbBackedValue, write: (newValue) => { dbBackedValue = newValue; myComputed.notifySubscribers(newValue); }, // 手动指定永远不自动销毁 disposeWhen: () => false });
额外说明
如果数据库的值可能被外部系统修改,需要手动调用myComputed.notifySubscribers()来通知所有订阅者更新——因为普通变量的变更无法被Knockout自动追踪。
内容的提问来源于stack exchange,提问作者Gunther Schadow
相关产品推荐
相关产品推荐

